From 6830e471bb3d5134104c81b1423640fd48770cac Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Fri, 26 Jul 2024 04:02:42 +1000 Subject: [PATCH 01/46] Remove unused i18n strings (#10220) --- .../access-selector/access-selector.component.ts | 4 ++-- apps/web/src/locales/en/messages.json | 12 ------------ .../access-policy-selector.component.ts | 2 -- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts index 3d70ee18df3..08381b7368b 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts @@ -59,7 +59,7 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On /** * Updates the enabled/disabled state of provided row form group based on the item's readonly state. * If a row is enabled, it also updates the enabled/disabled state of the permission control - * based on the item's accessAllItems state and the current value of `permissionMode`. + * based on the current value of `permissionMode`. * @param controlRow - The form group for the row to update * @param item - The access item that is represented by the row */ @@ -74,7 +74,7 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On controlRow.enable(); // The enable() above also enables the permission control, so we need to disable it again - // Disable permission control if accessAllItems is enabled or not in Edit mode + // Disable permission control if not in Edit mode if (this.permissionMode != PermissionMode.Edit) { controlRow.controls.permission.disable(); } diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 5fd5065b5b4..9f1d15f6487 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -2799,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2850,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.ts index e8e17fd83bd..bf0091b619c 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/access-policy-selector.component.ts @@ -37,8 +37,6 @@ export class AccessPolicySelectorComponent implements ControlValueAccessor, OnIn /** * Updates the enabled/disabled state of provided row form group based on the item's readonly state. - * If a row is enabled, it also updates the enabled/disabled state of the permission control - * based on the item's accessAllItems state and the current value of `permissionMode`. * @param controlRow - The form group for the row to update * @param item - The access item that is represented by the row */ From c9d0cd207e1b3976ec82918085e85378fb918a11 Mon Sep 17 00:00:00 2001 From: Cesar Gonzalez Date: Thu, 25 Jul 2024 14:01:24 -0500 Subject: [PATCH 02/46] [PM-2858] Inline menu identity autofill (#9900) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [PM-2857] Introducing logic that handles adding a credit card from the inline menu * [PM-9342] Incorporating logic to handle multiple autocomplete values within a captured set of page details * [PM-9342] Incorporating logic to handle multiple autocomplete values within a captured set of page details * [PM-9342] Changing logic for how we identify new password fields to reflect a more assertive qualification * [PM-2857] Fixing an issue with how we identify ciphers in the inline menu * [PM-2857] Working through issues when adding a cipher from the inline menu for credit card ciphers * [PM-2857] Working through issues when adding a cipher from the inline menu for credit card ciphers * [PM-2857] Fixing an issue encountered with updating credit card info within the add/edit view * [PM-9342] Adding feedback from code review * [PM-5189] Fixing an issue where the port key for an inline menu element could potentially be undefined if the window focus changes too quickly * [PM-2857] Refactoring implementation for how we getCipherViews to ensure we only query card items when necessary * [PM-2857] Refactoring implementation to simplify how we create cipherViews when adding a new item * [PM-2857] Fixing an issue with how we store identity and card cipher views * [PM-2857] Fixing an issue with how we store identity and card cipher views * [PM-2857] Finalizing implementation, writing jest tests, refactoring smaller elements * [PM-2857] Finalizing implementation, writing jest tests, refactoring smaller elements * [PM-2857] Finalizing implementation, writing jest tests, refactoring smaller elements * [PM-2857] Finalizing implementation, writing jest tests, refactoring smaller elements * [PM-2857] Fixing an issue with how we store identity and card cipher views * [PM-2857] Finalizing jest tests * [PM-2857] Finalizing jest tests * [PM-2857] Adjusting an aspect of the inline menu icon * [PM-2857] Adjusting aspect of inline menu field qualification * [PM-2858] Inline menu identities autofill * [PM-2857] Adjusting aspect of inline menu field qualification * [PM-2858] Inline menu identities autofill * [PM-2858] Incorporating logic required to selectively show and fill identity ciphers * [PM-2858] Updating copy for unlock state to be generic * [PM-2857] Updating copy for unlock state to be generic * [PM-2857] Updating copy for unlock state to be generic * [PM-2858] Updating copy for unlock state to be generic * [PM-5189] Fixing an issue where we can potentially show the inline menu incorrectly after a user switches account * [PM-5189] Fixing an issue where we can potentially show the inline menu incorrectly after a user switches account * PM-4950 - Fix hint and verify delete components that had the data in the wrong place (#9877) * PM-4661: Add passkey.username as item.username (#9756) * Add incoming passkey.username as item.username * Driveby fix, was sending wrong username * added username to new-cipher too * Guarded the if-block * Update apps/browser/src/vault/popup/components/vault/add-edit.component.ts Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * Fixed broken test * fixed username on existing ciphers --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * PM-4878: Add passkey information to items when signing in (#9835) * Added username to subtitle * Added subName to cipher * Moved subName to component * Update apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.ts Co-authored-by: SmithThe4th * Fixed double code and added comment * Added changeDetection: ChangeDetectionStrategy.OnPush as per review --------- Co-authored-by: SmithThe4th * [AC-2791] Members page - finish component library refactors (#9727) * Replace PlatformUtilsService with ToastService * Remove unneeded templates * Implement table filtering function * Move member-only methods from base class to subclass * Move utility functions inside new MemberTableDataSource * Rename PeopleComponent to MembersComponent * [deps] Platform: Update angular-cli monorepo to v16.2.14 (#9380) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * [PM-8789] Move desktop_native into subcrate (#9682) * Move desktop_native into subcrate * Add publish = false to crates * [PM-6394] remove policy evaluator cache (#9807) * [PM-9364] Copy for Aggregate auto-scaling invoices for Teams and Enterprise customers (#9875) * Change the seat adjustment message * Move changes from en_GB file to en file * revert changes in en_GB file * Add feature flag to the change * use user verification as a part of key rotation (#9722) * Add the ability for custom validation logic to be injected into `UserVerificationDialogComponent` (#8770) * Introduce `verificationType` * Update template to use `verificationType` * Implement a path for `verificationType = 'custom'` * Delete `clientSideOnlyVerification` * Update `EnrollMasterPasswordResetComponent` to include a server-side hash check * Better describe the custom scenerio through comments * Add an example of the custom verficiation scenerio * Move execution of verification function into try/catch * Migrate existing uses of `clientSideOnlyVerification` * Use generic type option instead of casting * Change "given" to "determined" in a comment * Restructure the `org-redirect` guard to be Angular 17+ compliant (#9552) * Document the `org-redirect` guard in code * Make assertions about the way the `org-redirect` guard should behave * Restructure the `org-redirect` guard to be Angular 17+ compliant * Convert data parameter to function parameter * Convert a data parameter to a function parameter that was missed * Pass redirect function to default organization route * don't initialize kdf with validators, do it on first set (#9754) * add testids for attachments (#9892) * Bug fix - error toast in 2fa (#9623) * Bug fix - error toast in 2fa * Bug fix - Yubikey code obscured * 2FA error fix * [PM-5189] Fixing an issue where we can potentially show the inline menu incorrectly after a user switches account * [PM-5189] Fixing an issue where we can potentially show the inline menu incorrectly after a user switches account * [PM-5189] Fixing an issue where we can potentially show the inline menu incorrectly after a user switches account * [PM-2858] Fixing icon color * [PM-2858] Adding subtitle for identity inline menu list items * [PM-2858] Fixing jest tests * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through implementation of conditional identity fill logic on inline menu * [PM-2858] Working through identity field qualification for the inline menu * [PM-2858] Working through identity field qualification for the inline menu * [PM-2858] Working through identity field qualification for the inline menu * [PM-2858] Working through identity field qualification for the inline menu * [PM-2858] Working through identity field qualification for the inline menu * [PM-2858] Working through identity field qualification for the inline menu * [PM-2858] Scaffolding add new identity logic * [PM-2858] Implementing add new identity * [PM-2858] Implementing add new identity * [PM-2858] Scaffolding add new identity logic * [PM-2858] Scaffolding add new identity logic * [PM-2858] Scaffolding add new identity logic * [PM-2857] Fixing an issue with how we parse the last digits for credit card aria description * [PM-2857] Setting up logic to ensrue we use a set email address as a fallback for a username * [PM-2857] Fixing an issue with how we parse the last digits for credit card aria description * [PM-2858] Reverting forced email address in inline menu identity autofill * Restructure the `is-paid-org` guard to be Angular 17+ compliant (#9598) * Document that `is-paid-org` guard in code * Remove unused `MessagingService` dependency * Make assertions about the way the is-paid-org guard should behave * Restructure the `is-paid-org` guard to be Angular 17+ compliant * Random commit to get the build job moving * Undo previous commit * Bumped client version(s) (#9895) * [PM-9344] Clarify accepted user state (#9861) * Prefer `Needs confirmation` to `Accepted` display status This emphasizes that action is still required to complete setup. * Remove unused message * Bumped client version(s) (#9906) * Revert "Bumped client version(s) (#9906)" (#9907) This reverts commit 78c28297938eda53e7731fdf9f63d7baa7068d0d. * fix duo subscriptions and org vs individual duo setup (#9859) * [PM-5024] Migrate tax-info component (#9872) * Changes for the tax info migration * Return for invalid formgroup * Restructure the `org-permissions` guard to be Angular 17+ compliant (#9631) * Document the `org-permissions` guard in code * Restructure the `org-permissions` guard to be Angular 17+ compliant * Update the `org-permissions` guard to use `ToastService` * Simplify callback function sigantures * Remove unused test object * Fix updated route from merge * Restructure the `provider-permissions` guard to be Angular 17+ compliant (#9609) * Document the `provider-permissions` guard in code * Restructure the `provider-permissions` guard to be Angular 17+ compliant * [deps] Platform: Update @types/argon2-browser to v1.18.4 (#8180) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Bumped client version(s) (#9914) * [PM-7162] Cipher Form - Item Details (#9758) * [PM-7162] Fix weird angular error regarding disabled component bit-select * [PM-7162] Introduce CipherFormConfigService and related types * [PM-7162] Introduce CipherFormService * [PM-7162] Introduce the Item Details section component and the CipherFormContainer interface * [PM-7162] Introduce the CipherForm component * [PM-7162] Add strongly typed QueryParams to the add-edit-v2.component * [PM-7162] Export CipherForm from Vault Lib * [PM-7162] Use the CipherForm in Browser AddEditV2 * [PM-7162] Introduce CipherForm storybook * [PM-7162] Remove VaultPopupListFilterService dependency from NewItemDropDownV2 component * [PM-7162] Add support for content projection of attachment button * [PM-7162] Fix typo * [PM-7162] Cipher form service cleanup * [PM-7162] Move readonly collection notice to bit-hint * [PM-7162] Refactor CipherFormConfig type to enforce required properties with Typescript * [PM-7162] Fix storybook after config changes * [PM-7162] Use new add-edit component for clone route * [deps]: Update @yao-pkg/pkg to ^5.12.0 (#9820) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Autosync the updated translations (#9922) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Autosync the updated translations (#9923) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Autosync the updated translations (#9924) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * [AC-2830] Unable to create a free organization (#9917) * Resolve the issue free org creation * Check that the taxForm is touched * [PM-7162] Fix broken getter when original cipher is null (#9927) * [PM-8525] Edit Card (#9901) * initial add of card details section * add card number * update card brand when the card number changes * add year and month fields * add security code field * hide number and security code by default * add `id` for all form fields * update select options to match existing options * make year input numerical * only display card details for card ciphers * use style to set input height * handle numerical values for year * update heading when a brand is available * remove unused ref * use cardview types for the form * fix numerical input type * disable card details when in partial-edit mode * remove hardcoded height * update types for formBuilder * [PM-9440] Fix: handle undefined value in migration 66 (#9908) * fix: handle undefined value in migration 66 * fix: the if-statement was typo * Rename "encryptionAlgorithm" to "hashAlgorithmForEncryption" for clarity (#9891) * [PM-7972] Account switching integration with "remember email" functionality (#9750) * add account switching logic to login email service * enforce boolean and fix desktop account switcher order * [PM-9442] Add tests for undefined state values and proper emulation of ElectronStorageService in tests (#9910) * fix: handle undefined value in migration 66 * fix: the if-statement was typo * feat: duplicate error behavior in fake storage service * feat: fix all migrations that were setting undefined values * feat: add test for disabled fingrint in migration 66 * fix: default single user state saving undefined value to state * revert: awaiting floating promise gonna fix this in a separate PR * Revert "feat: fix all migrations that were setting undefined values" This reverts commit 034713256cee9a8e164295c88157fe33d8372c81. * feat: automatically convert save to remove * Revert "fix: default single user state saving undefined value to state" This reverts commit 6c36da6ba52f6886d0de2b502b3aaff7f122c3a7. * [AC-2805] Consolidated Billing UI Updates (#9893) * Add empty state for invoices * Make cards on create client dialog tabbable * Add space in $ / month per member * Mute text, remove (Monthly) and right align menu on clients table * Made used seats account for all users and fixed column sort for used/remaining * Resize pricing cards * Rename assignedSeats to occupiedSeats * [PM-9460][deps] Tools: Update electron to v31 (#9921) * [deps] Tools: Update electron to v31 * Bump version in electron-builder --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel James Smith * [AC-1452] Restrict access to 'Organization Info' and 'Two-Step Login' settings pages with a permission check (#9483) * Guard Organization Info route - Owners only * Guard TwoFactor route - Owners only and Organization must be able to use 2FA * Update guards to use function syntax --------- Co-authored-by: Addison Beck * [PM-9437] Use CollectionAccessDetailsResponse type now that is always the type returned from the API (#9951) * Add required env variables to desktop native build script (#9869) * [AC-2676] Remove paging logic from GroupsComponent (#9705) * remove infinite scroll, use virtual scroll instead * use TableDataSource for search * allow sorting by name * replacing PlatformUtilsService.showToast with ToastService * misc FIXMEs * [PM-9441] Catch and log exceptions during migration (#9905) * feat: catch and log exceptions during migration * Revert "feat: catch and log exceptions during migration" This reverts commit d68733b7e58120298974b350e496bb3e0c9af0d2. * feat: use log service to log migration errors * Autosync the updated translations (#9972) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Autosync the updated translations (#9973) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Updated codeowners for new design system team (#9913) * Updated codeowners for new design system team. * Moved Angular and Bootstrap dependencies * Moved additional dependencies. * Updated ownership Co-authored-by: Will Martin --------- Co-authored-by: Will Martin * [SM-1016] Fix new access token dialog (#9918) * swap to bit-dialog title & subtitle * remove dialogRef.disableClose & use toastService * Add shared two-factor-options component (#9767) * Communicate the upcoming client vault privacy changes to MSPs (#9994) * Add a banner notification to the provider portal * Feature flag the banner * Move banner copy to messages.json * Allow for dismissing the banner * Auth/PM-7321 - Registration with Email Verification - Registration Finish Component Implementation (#9653) * PM-7321 - Temp add input password * PM-7321 - update input password based on latest PR changes to test. * PM-7321 - Progress on testing input password component + RegistrationFinishComponent checks * PM-7321 - more progress on registration finish. * PM-7321 - Wire up RegistrationFinishRequest model + AccountApiService abstraction + implementation changes for new method. * PM-7321 - WIP Registration Finish - wiring up request building and API call on submit. * PM-7321 - WIP registratin finish * PM-7321 - WIP on creating registration-finish service + web override to add org invite handling * PM-7321 - (1) Move web-registration-finish svc to web (2) Wire up exports (3) wire up RegistrationFinishComponent to call registration finish service * PM-7321 - Get CLI building * PM-7321 - Move all finish registration service and content to registration-finish feature folder. * PM-7321 - Fix RegistrationFinishService config * PM-7321 - RegistrationFinishComponent- handlePasswordFormSubmit - error handling WIP * PM-7321 - InputPasswordComp - Update to accept masterPasswordPolicyOptions as input instead of retrieving it as parent components in different scenarios will need to retrieve the policies differently (e.g., orgInvite token in registration vs direct call via org id post SSO on set password) * PM-7321 - Registration Finish - Add web specific logic for retrieving master password policies and passing them into the input password component. * PM-7321 - Registration Start - Send email via query param to registration finish page so it can create masterKey * PM-7321 - InputPassword comp - (1) Add loading input (2) Add email validation to submit logic. * PM-7321 - Registration Finish - Add submitting state and pass into input password so that the rest of the registration process keeps the child form disabled. * PM-7321 - Registration Finish - use validation service for error handling. * PM-7321 - All register routes must be dynamic and change if the feature flag changes. * PM-7321 - Test registration finish services. * PM-7321 - RegisterRouteService - Add comment documenting why the service exists. * PM-7321 - Add missing input password translations to browser & desktop * PM-7321 - WebRegistrationFinishSvc - apply PR feedback * [deps] Autofill: Update rimraf to v5.0.8 (#10008) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * [PM-9318] Fix username on protonpass import (#9889) * Fix username field used for ProtonPass import ProtonPass has changed their export format and userName is not itemEmail * Import additional field itemUsername --------- Co-authored-by: Daniel James Smith * [PM-8943] Update QRious script initialization in Authenticator two-factor provider (#9926) * create onload() for qrious as well as error messaging if QR code cannot be displayed * button and message updates and formpromise removal * load QR script async * rename and reorder methods * Delete Unused Bits of StateService (#9858) * Delete Unused Bits of StateService * Fix Tests * remove getBgService for auth request service (#10020) * [PM-2858] Fixing an issue found when the first or last names of an identity are not filled * [PM-2858] Fixing an issue found where keyboard navigation can potentially close the inline menu * [PM-2858] Fixing jest tests within inline menu list * [PM-2858] Fixing jest tests within inline menu list * [PM-2858] Setting up login items to be presented when an account creation form is shown to the user * [PM-2858] Refactoring implementation used for creating the inline menu cipher data * [PM-2858] Refactoring implementation used for creating the inline menu cipher data * [PM-2858] Refactoring implementation used for creating the inline menu cipher data * [PM-2858] Refactoring implementation * [PM-2858] Refactoring implementation * [PM-2858] Refactoring implementation * [PM-2858] Refactoring implementation * [PM-2858] Changing how we populate login ciphers within create account * [PM-2858] Adding documentation * [PM-2858] Working through jest tests for the OverlayBackground * [PM-2858] Working through jest tests for the OverlayBackground * [PM-2858] Working through jest tests for the AutofillInlineMenuList class * [PM-2858] Adding documentation to inline menu list methods * [PM-2857] Fixing a jest test * [PM-2858] Fixing jest tests within inline menu list * [PM-2858] Addressing jest tests within AutofillOverlayContentService * [PM-2858] Addressing jest tests within AutofillOverlayContentService * [PM-2858] Addressing jest tests within InlineMenuFieldQualificationService * [PM-9267] Implement feature flag for inline menu re-architecture (#9845) * [PM-9267] Implement Feature Flag for Inline Menu Re-Architecture * [PM-9267] Incorporating legacy OverlayBackground implementation * [PM-9267] Incorporating legacy overlay content scripts * [PM-9267] Incorporating legacy overlay content scripts * [PM-9267] Incorporating legacy overlay content scripts * [PM-9267] Incorporating legacy overlay content scripts * [PM-9267] Finalizing feature flag implementation * [PM-9267] Finalizing feature flag implementation * [PM-9267] Finalizing feature flag implementation * [PM-9267] Finalizing feature flag implementation * [PM-9267] Finalizing feature flag implementation * [PM-9267] Finalizing feature flag implementation * [PM-9267] Finalizing feature flag implementation * [PM-9267] Finalizing feature flag implementation * [PM-9267] Adjusting naming convention for page files * [PM-9267] Adjusting naming convention for page files * [PM-5189] Fixing an issue where we can potentially show the inline menu incorrectly after a user switches account * PM-4950 - Fix hint and verify delete components that had the data in the wrong place (#9877) * PM-4661: Add passkey.username as item.username (#9756) * Add incoming passkey.username as item.username * Driveby fix, was sending wrong username * added username to new-cipher too * Guarded the if-block * Update apps/browser/src/vault/popup/components/vault/add-edit.component.ts Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * Fixed broken test * fixed username on existing ciphers --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * PM-4878: Add passkey information to items when signing in (#9835) * Added username to subtitle * Added subName to cipher * Moved subName to component * Update apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.ts Co-authored-by: SmithThe4th * Fixed double code and added comment * Added changeDetection: ChangeDetectionStrategy.OnPush as per review --------- Co-authored-by: SmithThe4th * [AC-2791] Members page - finish component library refactors (#9727) * Replace PlatformUtilsService with ToastService * Remove unneeded templates * Implement table filtering function * Move member-only methods from base class to subclass * Move utility functions inside new MemberTableDataSource * Rename PeopleComponent to MembersComponent * [deps] Platform: Update angular-cli monorepo to v16.2.14 (#9380) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * [PM-8789] Move desktop_native into subcrate (#9682) * Move desktop_native into subcrate * Add publish = false to crates * [PM-6394] remove policy evaluator cache (#9807) * [PM-9364] Copy for Aggregate auto-scaling invoices for Teams and Enterprise customers (#9875) * Change the seat adjustment message * Move changes from en_GB file to en file * revert changes in en_GB file * Add feature flag to the change * use user verification as a part of key rotation (#9722) * Add the ability for custom validation logic to be injected into `UserVerificationDialogComponent` (#8770) * Introduce `verificationType` * Update template to use `verificationType` * Implement a path for `verificationType = 'custom'` * Delete `clientSideOnlyVerification` * Update `EnrollMasterPasswordResetComponent` to include a server-side hash check * Better describe the custom scenerio through comments * Add an example of the custom verficiation scenerio * Move execution of verification function into try/catch * Migrate existing uses of `clientSideOnlyVerification` * Use generic type option instead of casting * Change "given" to "determined" in a comment * Restructure the `org-redirect` guard to be Angular 17+ compliant (#9552) * Document the `org-redirect` guard in code * Make assertions about the way the `org-redirect` guard should behave * Restructure the `org-redirect` guard to be Angular 17+ compliant * Convert data parameter to function parameter * Convert a data parameter to a function parameter that was missed * Pass redirect function to default organization route * don't initialize kdf with validators, do it on first set (#9754) * add testids for attachments (#9892) * Bug fix - error toast in 2fa (#9623) * Bug fix - error toast in 2fa * Bug fix - Yubikey code obscured * 2FA error fix * Restructure the `is-paid-org` guard to be Angular 17+ compliant (#9598) * Document that `is-paid-org` guard in code * Remove unused `MessagingService` dependency * Make assertions about the way the is-paid-org guard should behave * Restructure the `is-paid-org` guard to be Angular 17+ compliant * Random commit to get the build job moving * Undo previous commit * Bumped client version(s) (#9895) * [PM-9344] Clarify accepted user state (#9861) * Prefer `Needs confirmation` to `Accepted` display status This emphasizes that action is still required to complete setup. * Remove unused message * Bumped client version(s) (#9906) * Revert "Bumped client version(s) (#9906)" (#9907) This reverts commit 78c28297938eda53e7731fdf9f63d7baa7068d0d. * fix duo subscriptions and org vs individual duo setup (#9859) * [PM-5024] Migrate tax-info component (#9872) * Changes for the tax info migration * Return for invalid formgroup * Restructure the `org-permissions` guard to be Angular 17+ compliant (#9631) * Document the `org-permissions` guard in code * Restructure the `org-permissions` guard to be Angular 17+ compliant * Update the `org-permissions` guard to use `ToastService` * Simplify callback function sigantures * Remove unused test object * Fix updated route from merge * Restructure the `provider-permissions` guard to be Angular 17+ compliant (#9609) * Document the `provider-permissions` guard in code * Restructure the `provider-permissions` guard to be Angular 17+ compliant * [deps] Platform: Update @types/argon2-browser to v1.18.4 (#8180) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Bumped client version(s) (#9914) * [PM-7162] Cipher Form - Item Details (#9758) * [PM-7162] Fix weird angular error regarding disabled component bit-select * [PM-7162] Introduce CipherFormConfigService and related types * [PM-7162] Introduce CipherFormService * [PM-7162] Introduce the Item Details section component and the CipherFormContainer interface * [PM-7162] Introduce the CipherForm component * [PM-7162] Add strongly typed QueryParams to the add-edit-v2.component * [PM-7162] Export CipherForm from Vault Lib * [PM-7162] Use the CipherForm in Browser AddEditV2 * [PM-7162] Introduce CipherForm storybook * [PM-7162] Remove VaultPopupListFilterService dependency from NewItemDropDownV2 component * [PM-7162] Add support for content projection of attachment button * [PM-7162] Fix typo * [PM-7162] Cipher form service cleanup * [PM-7162] Move readonly collection notice to bit-hint * [PM-7162] Refactor CipherFormConfig type to enforce required properties with Typescript * [PM-7162] Fix storybook after config changes * [PM-7162] Use new add-edit component for clone route * [deps]: Update @yao-pkg/pkg to ^5.12.0 (#9820) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Autosync the updated translations (#9922) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Autosync the updated translations (#9923) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Autosync the updated translations (#9924) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * [AC-2830] Unable to create a free organization (#9917) * Resolve the issue free org creation * Check that the taxForm is touched * [PM-7162] Fix broken getter when original cipher is null (#9927) * [PM-8525] Edit Card (#9901) * initial add of card details section * add card number * update card brand when the card number changes * add year and month fields * add security code field * hide number and security code by default * add `id` for all form fields * update select options to match existing options * make year input numerical * only display card details for card ciphers * use style to set input height * handle numerical values for year * update heading when a brand is available * remove unused ref * use cardview types for the form * fix numerical input type * disable card details when in partial-edit mode * remove hardcoded height * update types for formBuilder * [PM-9440] Fix: handle undefined value in migration 66 (#9908) * fix: handle undefined value in migration 66 * fix: the if-statement was typo * Rename "encryptionAlgorithm" to "hashAlgorithmForEncryption" for clarity (#9891) * [PM-7972] Account switching integration with "remember email" functionality (#9750) * add account switching logic to login email service * enforce boolean and fix desktop account switcher order * [PM-9442] Add tests for undefined state values and proper emulation of ElectronStorageService in tests (#9910) * fix: handle undefined value in migration 66 * fix: the if-statement was typo * feat: duplicate error behavior in fake storage service * feat: fix all migrations that were setting undefined values * feat: add test for disabled fingrint in migration 66 * fix: default single user state saving undefined value to state * revert: awaiting floating promise gonna fix this in a separate PR * Revert "feat: fix all migrations that were setting undefined values" This reverts commit 034713256cee9a8e164295c88157fe33d8372c81. * feat: automatically convert save to remove * Revert "fix: default single user state saving undefined value to state" This reverts commit 6c36da6ba52f6886d0de2b502b3aaff7f122c3a7. * [AC-2805] Consolidated Billing UI Updates (#9893) * Add empty state for invoices * Make cards on create client dialog tabbable * Add space in $ / month per member * Mute text, remove (Monthly) and right align menu on clients table * Made used seats account for all users and fixed column sort for used/remaining * Resize pricing cards * Rename assignedSeats to occupiedSeats * [PM-9460][deps] Tools: Update electron to v31 (#9921) * [deps] Tools: Update electron to v31 * Bump version in electron-builder --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel James Smith * [AC-1452] Restrict access to 'Organization Info' and 'Two-Step Login' settings pages with a permission check (#9483) * Guard Organization Info route - Owners only * Guard TwoFactor route - Owners only and Organization must be able to use 2FA * Update guards to use function syntax --------- Co-authored-by: Addison Beck * [PM-9437] Use CollectionAccessDetailsResponse type now that is always the type returned from the API (#9951) * Add required env variables to desktop native build script (#9869) * [AC-2676] Remove paging logic from GroupsComponent (#9705) * remove infinite scroll, use virtual scroll instead * use TableDataSource for search * allow sorting by name * replacing PlatformUtilsService.showToast with ToastService * misc FIXMEs * [PM-9441] Catch and log exceptions during migration (#9905) * feat: catch and log exceptions during migration * Revert "feat: catch and log exceptions during migration" This reverts commit d68733b7e58120298974b350e496bb3e0c9af0d2. * feat: use log service to log migration errors * Autosync the updated translations (#9972) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Autosync the updated translations (#9973) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> * Updated codeowners for new design system team (#9913) * Updated codeowners for new design system team. * Moved Angular and Bootstrap dependencies * Moved additional dependencies. * Updated ownership Co-authored-by: Will Martin --------- Co-authored-by: Will Martin * [SM-1016] Fix new access token dialog (#9918) * swap to bit-dialog title & subtitle * remove dialogRef.disableClose & use toastService * Add shared two-factor-options component (#9767) * Communicate the upcoming client vault privacy changes to MSPs (#9994) * Add a banner notification to the provider portal * Feature flag the banner * Move banner copy to messages.json * Allow for dismissing the banner * Auth/PM-7321 - Registration with Email Verification - Registration Finish Component Implementation (#9653) * PM-7321 - Temp add input password * PM-7321 - update input password based on latest PR changes to test. * PM-7321 - Progress on testing input password component + RegistrationFinishComponent checks * PM-7321 - more progress on registration finish. * PM-7321 - Wire up RegistrationFinishRequest model + AccountApiService abstraction + implementation changes for new method. * PM-7321 - WIP Registration Finish - wiring up request building and API call on submit. * PM-7321 - WIP registratin finish * PM-7321 - WIP on creating registration-finish service + web override to add org invite handling * PM-7321 - (1) Move web-registration-finish svc to web (2) Wire up exports (3) wire up RegistrationFinishComponent to call registration finish service * PM-7321 - Get CLI building * PM-7321 - Move all finish registration service and content to registration-finish feature folder. * PM-7321 - Fix RegistrationFinishService config * PM-7321 - RegistrationFinishComponent- handlePasswordFormSubmit - error handling WIP * PM-7321 - InputPasswordComp - Update to accept masterPasswordPolicyOptions as input instead of retrieving it as parent components in different scenarios will need to retrieve the policies differently (e.g., orgInvite token in registration vs direct call via org id post SSO on set password) * PM-7321 - Registration Finish - Add web specific logic for retrieving master password policies and passing them into the input password component. * PM-7321 - Registration Start - Send email via query param to registration finish page so it can create masterKey * PM-7321 - InputPassword comp - (1) Add loading input (2) Add email validation to submit logic. * PM-7321 - Registration Finish - Add submitting state and pass into input password so that the rest of the registration process keeps the child form disabled. * PM-7321 - Registration Finish - use validation service for error handling. * PM-7321 - All register routes must be dynamic and change if the feature flag changes. * PM-7321 - Test registration finish services. * PM-7321 - RegisterRouteService - Add comment documenting why the service exists. * PM-7321 - Add missing input password translations to browser & desktop * PM-7321 - WebRegistrationFinishSvc - apply PR feedback * [deps] Autofill: Update rimraf to v5.0.8 (#10008) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * [PM-9318] Fix username on protonpass import (#9889) * Fix username field used for ProtonPass import ProtonPass has changed their export format and userName is not itemEmail * Import additional field itemUsername --------- Co-authored-by: Daniel James Smith * [PM-8943] Update QRious script initialization in Authenticator two-factor provider (#9926) * create onload() for qrious as well as error messaging if QR code cannot be displayed * button and message updates and formpromise removal * load QR script async * rename and reorder methods * Delete Unused Bits of StateService (#9858) * Delete Unused Bits of StateService * Fix Tests * remove getBgService for auth request service (#10020) --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Co-authored-by: Anders Åberg Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> Co-authored-by: SmithThe4th Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel García Co-authored-by: ✨ Audrey ✨ Co-authored-by: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Co-authored-by: Jake Fink Co-authored-by: Addison Beck Co-authored-by: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Co-authored-by: vinith-kovan <156108204+vinith-kovan@users.noreply.github.com> Co-authored-by: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Co-authored-by: Matt Gibson Co-authored-by: Opeyemi Co-authored-by: Shane Melton Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Andreas Coroiu Co-authored-by: Bernd Schoolmann Co-authored-by: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Co-authored-by: Daniel James Smith Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com> Co-authored-by: Addison Beck Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com> Co-authored-by: Will Martin Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Co-authored-by: Ike <137194738+ike-kottlowski@users.noreply.github.com> * [PM-2858] Fixing an issue found where password fields addedin new account forms do not properly pull their value into the add cipher flow * [PM-2858] Adjusting scrollbar stylings * [PM-2858] Adjusting how we handle instantiating the feature flag guarded overlay background and how we handle instantiating identities and card ciphers in the inline menu * [PM-2858] Adjusting how we handle instantiating the feature flag guarded overlay background and how we handle instantiating identities and card ciphers in the inline menu * [PM-2858] Adjusting how we handle instantiating the feature flag guarded overlay background and how we handle instantiating identities and card ciphers in the inline menu * [PM-2858] Incorporating some changes that ensure the inline menu list fades in as expected * [PM-2858] Incorporating some changes that ensure the inline menu list fades in as expected * [PM-2858] Incorporating some changes that ensure the inline menu list fades in as expected * [PM-2858] Adjusting how we inject translations for a couple of aria label elements * [PM-2858] Fixing duplicate globalThis references --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Co-authored-by: Anders Åberg Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> Co-authored-by: SmithThe4th Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel García Co-authored-by: ✨ Audrey ✨ Co-authored-by: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Co-authored-by: Jake Fink Co-authored-by: Addison Beck Co-authored-by: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Co-authored-by: vinith-kovan <156108204+vinith-kovan@users.noreply.github.com> Co-authored-by: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Co-authored-by: Matt Gibson Co-authored-by: Opeyemi Co-authored-by: Shane Melton Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Andreas Coroiu Co-authored-by: Bernd Schoolmann Co-authored-by: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Co-authored-by: Daniel James Smith Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com> Co-authored-by: Addison Beck Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com> Co-authored-by: Will Martin Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Co-authored-by: Ike <137194738+ike-kottlowski@users.noreply.github.com> --- apps/browser/src/_locales/en/messages.json | 20 +- .../abstractions/overlay.background.ts | 29 +- .../background/overlay.background.spec.ts | 346 ++++++++- .../autofill/background/overlay.background.ts | 331 ++++++++- .../content/autofill-init.deprecated.spec.ts | 11 +- ...ofill-overlay-list.deprecated.spec.ts.snap | 9 +- .../autofill/enums/autofill-field.enums.ts | 29 + .../src/autofill/models/autofill-field.ts | 6 + .../abstractions/autofill-inline-menu-list.ts | 2 + .../autofill-inline-menu-content.service.ts | 7 +- .../autofill-inline-menu-iframe.service.ts | 19 +- .../autofill-inline-menu-list.spec.ts.snap | 693 ++++++++++++++++-- .../list/autofill-inline-menu-list.spec.ts | 165 ++++- .../pages/list/autofill-inline-menu-list.ts | 260 +++++-- .../overlay/inline-menu/pages/list/list.scss | 57 +- .../autofill-inline-menu-page-element.ts | 6 +- ...nline-menu-field-qualifications.service.ts | 21 + .../autofill/services/autofill-constants.ts | 16 +- .../autofill-overlay-content.service.spec.ts | 398 +++++++++- .../autofill-overlay-content.service.ts | 214 +++++- .../src/autofill/services/autofill.service.ts | 5 +- .../collect-autofill-content.service.ts | 4 +- ...e-menu-field-qualification.service.spec.ts | 73 +- ...inline-menu-field-qualification.service.ts | 479 +++++++++++- .../src/autofill/spec/autofill-mocks.ts | 9 +- apps/browser/src/autofill/utils/index.spec.ts | 23 +- apps/browser/src/autofill/utils/index.ts | 12 +- apps/browser/src/autofill/utils/svg-icons.ts | 2 +- .../browser/src/background/main.background.ts | 96 +-- 29 files changed, 3020 insertions(+), 322 deletions(-) create mode 100644 apps/browser/src/autofill/enums/autofill-field.enums.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index d908b267f4b..bf2b26a11b5 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -3054,6 +3054,10 @@ "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -3078,18 +3082,26 @@ "message": "New login", "description": "Button text to display within inline menu when there are no matching items on a login field" }, - "addNewLoginItem": { - "message": "Add new vault login item", + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { "message": "New card", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, - "addNewCardItem": { - "message": "Add new vault card item", + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", "description": "Screen reader text (aria-label) for new card button within inline menu" }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" diff --git a/apps/browser/src/autofill/background/abstractions/overlay.background.ts b/apps/browser/src/autofill/background/abstractions/overlay.background.ts index 763261cae26..f1bfd3642fa 100644 --- a/apps/browser/src/autofill/background/abstractions/overlay.background.ts +++ b/apps/browser/src/autofill/background/abstractions/overlay.background.ts @@ -37,6 +37,8 @@ export type FocusedFieldData = { filledByCipherType?: CipherType; tabId?: number; frameId?: number; + accountCreationFieldType?: string; + showInlineMenuAccountCreation?: boolean; }; export type InlineMenuElementPosition = { @@ -67,10 +69,30 @@ export type NewCardCipherData = { cvv: string; }; +export type NewIdentityCipherData = { + title: string; + firstName: string; + middleName: string; + lastName: string; + fullName: string; + address1: string; + address2: string; + address3: string; + city: string; + state: string; + postalCode: string; + country: string; + company: string; + phone: string; + email: string; + username: string; +}; + export type OverlayAddNewItemMessage = { addNewCipherType?: CipherType; login?: NewLoginCipherData; card?: NewCardCipherData; + identity?: NewIdentityCipherData; }; export type CloseInlineMenuMessage = { @@ -115,8 +137,13 @@ export type InlineMenuCipherData = { reprompt: CipherRepromptType; favorite: boolean; icon: WebsiteIconData; + accountCreationFieldType?: string; login?: { username: string }; card?: string; + identity?: { + fullName: string; + username?: string; + }; }; export type BackgroundMessageParam = { @@ -180,7 +207,7 @@ export type PortOnMessageHandlerParams = PortMessageParam & PortConnectionParam; export type InlineMenuButtonPortMessageHandlers = { [key: string]: CallableFunction; - triggerDelayedAutofillInlineMenuClosure: ({ port }: PortConnectionParam) => void; + triggerDelayedAutofillInlineMenuClosure: () => void; autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void; autofillInlineMenuBlurred: () => void; redirectAutofillInlineMenuFocusOut: ({ message, port }: PortOnMessageHandlerParams) => void; diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index de668cd8178..3a3bb7dd5e8 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -43,11 +43,11 @@ import { } from "../enums/autofill-overlay.enum"; import { AutofillService } from "../services/abstractions/autofill.service"; import { - createChromeTabMock, createAutofillPageDetailsMock, - createPortSpyMock, + createChromeTabMock, createFocusedFieldDataMock, createPageDetailMock, + createPortSpyMock, } from "../spec/autofill-mocks"; import { flushPromises, @@ -713,9 +713,22 @@ describe("OverlayBackground", () => { type: CipherType.Login, login: { username: "username-3", uri: url }, }); + const cipher4 = mock({ + id: "id-4", + localData: { lastUsedDate: 222 }, + name: "name-4", + type: CipherType.Identity, + identity: { + username: "username", + firstName: "Test", + lastName: "User", + email: "email@example.com", + }, + }); - beforeEach(() => { + beforeEach(async () => { activeAccountStatusMock$.next(AuthenticationStatus.Unlocked); + await initOverlayElementPorts(); }); it("skips updating the overlay ciphers if the user's auth status is not unlocked", async () => { @@ -767,7 +780,10 @@ describe("OverlayBackground", () => { await overlayBackground.updateOverlayCiphers(); expect(BrowserApi.getTabFromCurrentWindowId).toHaveBeenCalled(); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, [CipherType.Card]); + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, [ + CipherType.Card, + CipherType.Identity, + ]); expect(cipherService.sortCiphersByLastUsedThenName).toHaveBeenCalled(); expect(overlayBackground["inlineMenuCiphers"]).toStrictEqual( new Map([ @@ -804,7 +820,10 @@ describe("OverlayBackground", () => { await overlayBackground.updateOverlayCiphers(false); expect(BrowserApi.getTabFromCurrentWindowId).toHaveBeenCalled(); - expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, [CipherType.Card]); + expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url, [ + CipherType.Card, + CipherType.Identity, + ]); expect(cipherService.sortCiphersByLastUsedThenName).toHaveBeenCalled(); expect(overlayBackground["inlineMenuCiphers"]).toStrictEqual( new Map([ @@ -815,7 +834,6 @@ describe("OverlayBackground", () => { }); it("posts an `updateOverlayListCiphers` message to the overlay list port, and send a `updateAutofillInlineMenuListCiphers` message to the tab indicating that the list of ciphers is populated", async () => { - overlayBackground["inlineMenuListPort"] = mock(); overlayBackground["focusedFieldData"] = createFocusedFieldDataMock({ tabId: tab.id }); cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher1, cipher2]); cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1); @@ -823,11 +841,12 @@ describe("OverlayBackground", () => { await overlayBackground.updateOverlayCiphers(); - expect(overlayBackground["inlineMenuListPort"].postMessage).toHaveBeenCalledWith({ + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ command: "updateAutofillInlineMenuListCiphers", + showInlineMenuAccountCreation: false, ciphers: [ { - card: null, + accountCreationFieldType: undefined, favorite: cipher1.favorite, icon: { fallbackImage: "images/bwi-globe.png", @@ -846,6 +865,205 @@ describe("OverlayBackground", () => { ], }); }); + + it("updates the inline menu list with card ciphers", async () => { + overlayBackground["focusedFieldData"] = createFocusedFieldDataMock({ + tabId: tab.id, + filledByCipherType: CipherType.Card, + }); + cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher1, cipher2]); + cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1); + getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(tab); + + await overlayBackground.updateOverlayCiphers(); + + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ + command: "updateAutofillInlineMenuListCiphers", + showInlineMenuAccountCreation: false, + ciphers: [ + { + accountCreationFieldType: undefined, + favorite: cipher2.favorite, + icon: { + fallbackImage: "", + icon: "bwi-credit-card", + image: undefined, + imageEnabled: true, + }, + id: "inline-menu-cipher-0", + card: cipher2.card.subTitle, + name: cipher2.name, + reprompt: cipher2.reprompt, + type: CipherType.Card, + }, + ], + }); + }); + + describe("updating ciphers for an account creation inline menu", () => { + it("updates the ciphers with a list of identity ciphers that contain a username", async () => { + overlayBackground["focusedFieldData"] = createFocusedFieldDataMock({ + tabId: tab.id, + accountCreationFieldType: "text", + showInlineMenuAccountCreation: true, + }); + cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher4, cipher2]); + cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1); + getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(tab); + + await overlayBackground.updateOverlayCiphers(); + + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ + command: "updateAutofillInlineMenuListCiphers", + showInlineMenuAccountCreation: true, + ciphers: [ + { + accountCreationFieldType: "text", + favorite: cipher4.favorite, + icon: { + fallbackImage: "", + icon: "bwi-id-card", + image: undefined, + imageEnabled: true, + }, + id: "inline-menu-cipher-1", + name: cipher4.name, + reprompt: cipher4.reprompt, + type: CipherType.Identity, + identity: { + fullName: `${cipher4.identity.firstName} ${cipher4.identity.lastName}`, + username: cipher4.identity.username, + }, + }, + ], + }); + }); + + it("appends any found login ciphers to the list of identity ciphers", async () => { + overlayBackground["focusedFieldData"] = createFocusedFieldDataMock({ + tabId: tab.id, + accountCreationFieldType: "text", + showInlineMenuAccountCreation: true, + }); + cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher1, cipher4]); + cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1); + getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(tab); + + await overlayBackground.updateOverlayCiphers(); + + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ + command: "updateAutofillInlineMenuListCiphers", + showInlineMenuAccountCreation: true, + ciphers: [ + { + accountCreationFieldType: "text", + favorite: cipher4.favorite, + icon: { + fallbackImage: "", + icon: "bwi-id-card", + image: undefined, + imageEnabled: true, + }, + id: "inline-menu-cipher-0", + name: cipher4.name, + reprompt: cipher4.reprompt, + type: CipherType.Identity, + identity: { + fullName: `${cipher4.identity.firstName} ${cipher4.identity.lastName}`, + username: cipher4.identity.username, + }, + }, + { + accountCreationFieldType: "text", + favorite: cipher1.favorite, + icon: { + fallbackImage: "images/bwi-globe.png", + icon: "bwi-globe", + image: "https://icons.bitwarden.com//jest-testing-website.com/icon.png", + imageEnabled: true, + }, + id: "inline-menu-cipher-1", + login: { + username: cipher1.login.username, + }, + name: cipher1.name, + reprompt: cipher1.reprompt, + type: CipherType.Login, + }, + ], + }); + }); + + it("skips any identity ciphers that do not contain a username or an email address", async () => { + overlayBackground["focusedFieldData"] = createFocusedFieldDataMock({ + tabId: tab.id, + accountCreationFieldType: "email", + showInlineMenuAccountCreation: true, + }); + const identityCipherWithoutUsername = mock({ + id: "id-5", + localData: { lastUsedDate: 222 }, + name: "name-5", + type: CipherType.Identity, + identity: { + username: "", + email: "", + }, + }); + cipherService.getAllDecryptedForUrl.mockResolvedValue([ + cipher4, + identityCipherWithoutUsername, + ]); + cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1); + getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(tab); + + await overlayBackground.updateOverlayCiphers(); + + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ + command: "updateAutofillInlineMenuListCiphers", + showInlineMenuAccountCreation: true, + ciphers: [ + { + accountCreationFieldType: "email", + favorite: cipher4.favorite, + icon: { + fallbackImage: "", + icon: "bwi-id-card", + image: undefined, + imageEnabled: true, + }, + id: "inline-menu-cipher-1", + name: cipher4.name, + reprompt: cipher4.reprompt, + type: CipherType.Identity, + identity: { + fullName: `${cipher4.identity.firstName} ${cipher4.identity.lastName}`, + username: cipher4.identity.email, + }, + }, + ], + }); + }); + + it("does not add the identity ciphers if the field is for a password field", async () => { + overlayBackground["focusedFieldData"] = createFocusedFieldDataMock({ + tabId: tab.id, + accountCreationFieldType: "password", + showInlineMenuAccountCreation: true, + }); + cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher4]); + cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1); + getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(tab); + + await overlayBackground.updateOverlayCiphers(); + + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ + command: "updateAutofillInlineMenuListCiphers", + showInlineMenuAccountCreation: true, + ciphers: [], + }); + }); + }); }); describe("extension message handlers", () => { @@ -954,6 +1172,95 @@ describe("OverlayBackground", () => { expect(sendMessageSpy).toHaveBeenCalledWith("inlineAutofillMenuRefreshAddEditCipher"); expect(openAddEditVaultItemPopoutSpy).toHaveBeenCalled(); }); + + describe("creating a new identity cipher", () => { + it("populates an identity cipher view and creates it", async () => { + sendMockExtensionMessage( + { + command: "autofillOverlayAddNewVaultItem", + addNewCipherType: CipherType.Identity, + identity: { + title: "title", + firstName: "firstName", + middleName: "middleName", + lastName: "lastName", + fullName: "fullName", + address1: "address1", + address2: "address2", + address3: "address3", + city: "city", + state: "state", + postalCode: "postalCode", + country: "country", + company: "company", + phone: "phone", + email: "email", + username: "username", + }, + }, + sender, + ); + await flushPromises(); + + expect(cipherService.setAddEditCipherInfo).toHaveBeenCalled(); + expect(sendMessageSpy).toHaveBeenCalledWith("inlineAutofillMenuRefreshAddEditCipher"); + expect(openAddEditVaultItemPopoutSpy).toHaveBeenCalled(); + }); + + it("saves the first name based on the full name value", async () => { + sendMockExtensionMessage( + { + command: "autofillOverlayAddNewVaultItem", + addNewCipherType: CipherType.Identity, + identity: { + firstName: "", + lastName: "", + fullName: "fullName", + }, + }, + sender, + ); + await flushPromises(); + + expect(cipherService.setAddEditCipherInfo).toHaveBeenCalled(); + }); + + it("saves the first and middle names based on the full name value", async () => { + sendMockExtensionMessage( + { + command: "autofillOverlayAddNewVaultItem", + addNewCipherType: CipherType.Identity, + identity: { + firstName: "", + lastName: "", + fullName: "firstName middleName", + }, + }, + sender, + ); + await flushPromises(); + + expect(cipherService.setAddEditCipherInfo).toHaveBeenCalled(); + }); + + it("saves the first, middle, and last names based on the full name value", async () => { + sendMockExtensionMessage( + { + command: "autofillOverlayAddNewVaultItem", + addNewCipherType: CipherType.Identity, + identity: { + firstName: "", + lastName: "", + fullName: "firstName middleName lastName", + }, + }, + sender, + ); + await flushPromises(); + + expect(cipherService.setAddEditCipherInfo).toHaveBeenCalled(); + }); + }); }); describe("checkIsInlineMenuCiphersPopulated message handler", () => { @@ -1030,6 +1337,29 @@ describe("OverlayBackground", () => { { frameId: firstSender.frameId }, ); }); + + it("triggers an update of the identity ciphers present on a login field", async () => { + await initOverlayElementPorts(); + activeAccountStatusMock$.next(AuthenticationStatus.Unlocked); + const tab = createChromeTabMock({ id: 2 }); + overlayBackground["focusedFieldData"] = createFocusedFieldDataMock(); + overlayBackground["isInlineMenuButtonVisible"] = true; + const sender = mock({ tab, frameId: 100 }); + const focusedFieldData = createFocusedFieldDataMock({ + tabId: tab.id, + frameId: sender.frameId, + showInlineMenuAccountCreation: true, + }); + + sendMockExtensionMessage({ command: "updateFocusedFieldData", focusedFieldData }, sender); + await flushPromises(); + + expect(listPortSpy.postMessage).toHaveBeenCalledWith({ + command: "updateAutofillInlineMenuListCiphers", + ciphers: [], + showInlineMenuAccountCreation: true, + }); + }); }); describe("checkIsFieldCurrentlyFocused message handler", () => { diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index 76b0f4b76ec..eea72979dd2 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -21,6 +21,7 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { buildCipherIcon } from "@bitwarden/common/vault/icon/build-cipher-icon"; import { CardView } from "@bitwarden/common/vault/models/view/card.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view"; import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; @@ -40,23 +41,24 @@ import { generateRandomChars } from "../utils"; import { LockedVaultPendingNotificationsData } from "./abstractions/notification.background"; import { + CloseInlineMenuMessage, FocusedFieldData, + InlineMenuButtonPortMessageHandlers, + InlineMenuCipherData, + InlineMenuListPortMessageHandlers, + InlineMenuPosition, + NewCardCipherData, + NewIdentityCipherData, + NewLoginCipherData, OverlayAddNewItemMessage, OverlayBackground as OverlayBackgroundInterface, OverlayBackgroundExtensionMessage, OverlayBackgroundExtensionMessageHandlers, - InlineMenuButtonPortMessageHandlers, - InlineMenuCipherData, - InlineMenuListPortMessageHandlers, OverlayPortMessage, PageDetailsForTab, SubFrameOffsetData, SubFrameOffsetsForTab, - CloseInlineMenuMessage, - InlineMenuPosition, ToggleInlineMenuHiddenMessage, - NewLoginCipherData, - NewCardCipherData, } from "./abstractions/overlay.background"; export class OverlayBackground implements OverlayBackgroundInterface { @@ -125,7 +127,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { deletedCipher: () => this.updateOverlayCiphers(), }; private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = { - triggerDelayedAutofillInlineMenuClosure: ({ port }) => this.triggerDelayedInlineMenuClosure(), + triggerDelayedAutofillInlineMenuClosure: () => this.triggerDelayedInlineMenuClosure(), autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port), autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(), redirectAutofillInlineMenuFocusOut: ({ message, port }) => @@ -249,6 +251,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { this.inlineMenuListPort?.postMessage({ command: "updateAutofillInlineMenuListCiphers", ciphers, + showInlineMenuAccountCreation: this.showInlineMenuAccountCreation(), }); } @@ -285,15 +288,25 @@ export class OverlayBackground implements OverlayBackgroundInterface { this.cardAndIdentityCiphers.clear(); const cipherViews = ( - await this.cipherService.getAllDecryptedForUrl(currentTab.url, [CipherType.Card]) + await this.cipherService.getAllDecryptedForUrl(currentTab.url, [ + CipherType.Card, + CipherType.Identity, + ]) ).sort((a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b)); for (let cipherIndex = 0; cipherIndex < cipherViews.length; cipherIndex++) { const cipherView = cipherViews[cipherIndex]; - if (cipherView.type === CipherType.Card && !this.cardAndIdentityCiphers.has(cipherView)) { + if ( + !this.cardAndIdentityCiphers.has(cipherView) && + [CipherType.Card, CipherType.Identity].includes(cipherView.type) + ) { this.cardAndIdentityCiphers.add(cipherView); } } + if (!this.cardAndIdentityCiphers.size) { + this.cardAndIdentityCiphers = null; + } + return cipherViews; } @@ -304,6 +317,75 @@ export class OverlayBackground implements OverlayBackgroundInterface { private async getInlineMenuCipherData(): Promise { const showFavicons = await firstValueFrom(this.domainSettingsService.showFavicons$); const inlineMenuCiphersArray = Array.from(this.inlineMenuCiphers); + let inlineMenuCipherData: InlineMenuCipherData[] = []; + + if (this.showInlineMenuAccountCreation()) { + inlineMenuCipherData = this.buildInlineMenuAccountCreationCiphers( + inlineMenuCiphersArray, + true, + ); + } else { + inlineMenuCipherData = this.buildInlineMenuCiphers(inlineMenuCiphersArray, showFavicons); + } + + this.currentInlineMenuCiphersCount = inlineMenuCipherData.length; + return inlineMenuCipherData; + } + + /** + * Builds the inline menu ciphers for a form field that is meant for account creation. + * + * @param inlineMenuCiphersArray - Array of inline menu ciphers + * @param showFavicons - Identifies whether favicons should be shown + */ + private buildInlineMenuAccountCreationCiphers( + inlineMenuCiphersArray: [string, CipherView][], + showFavicons: boolean, + ) { + const inlineMenuCipherData: InlineMenuCipherData[] = []; + const accountCreationLoginCiphers: InlineMenuCipherData[] = []; + + for (let cipherIndex = 0; cipherIndex < inlineMenuCiphersArray.length; cipherIndex++) { + const [inlineMenuCipherId, cipher] = inlineMenuCiphersArray[cipherIndex]; + + if (cipher.type === CipherType.Login) { + accountCreationLoginCiphers.push( + this.buildCipherData(inlineMenuCipherId, cipher, showFavicons, true), + ); + continue; + } + + if (cipher.type !== CipherType.Identity || !this.focusedFieldData?.accountCreationFieldType) { + continue; + } + + const identity = this.getIdentityCipherData(cipher, true); + if (!identity?.username) { + continue; + } + + inlineMenuCipherData.push( + this.buildCipherData(inlineMenuCipherId, cipher, showFavicons, true, identity), + ); + } + + if (accountCreationLoginCiphers.length) { + return inlineMenuCipherData.concat(accountCreationLoginCiphers); + } + + return inlineMenuCipherData; + } + + /** + * Builds the inline menu ciphers for a form field that is not meant for account creation. + * + * @param inlineMenuCiphersArray - Array of inline menu ciphers + * @param showFavicons - Identifies whether favicons should be shown + */ + private buildInlineMenuCiphers( + inlineMenuCiphersArray: [string, CipherView][], + showFavicons: boolean, + ) { const inlineMenuCipherData: InlineMenuCipherData[] = []; for (let cipherIndex = 0; cipherIndex < inlineMenuCiphersArray.length; cipherIndex++) { @@ -312,22 +394,111 @@ export class OverlayBackground implements OverlayBackgroundInterface { continue; } - inlineMenuCipherData.push({ - id: inlineMenuCipherId, - name: cipher.name, - type: cipher.type, - reprompt: cipher.reprompt, - favorite: cipher.favorite, - icon: buildCipherIcon(this.iconsServerUrl, cipher, showFavicons), - login: cipher.type === CipherType.Login ? { username: cipher.login.username } : null, - card: cipher.type === CipherType.Card ? cipher.card.subTitle : null, - }); + inlineMenuCipherData.push(this.buildCipherData(inlineMenuCipherId, cipher, showFavicons)); } - this.currentInlineMenuCiphersCount = inlineMenuCipherData.length; return inlineMenuCipherData; } + /** + * Builds the cipher data for the inline menu list. + * + * @param inlineMenuCipherId - The ID of the inline menu cipher + * @param cipher - The cipher to build data for + * @param showFavicons - Identifies whether favicons should be shown + * @param showInlineMenuAccountCreation - Identifies whether the inline menu is for account creation + * @param identityData - Pre-created identity data + */ + private buildCipherData( + inlineMenuCipherId: string, + cipher: CipherView, + showFavicons: boolean, + showInlineMenuAccountCreation: boolean = false, + identityData?: { fullName: string; username?: string }, + ): InlineMenuCipherData { + const inlineMenuData: InlineMenuCipherData = { + id: inlineMenuCipherId, + name: cipher.name, + type: cipher.type, + reprompt: cipher.reprompt, + favorite: cipher.favorite, + icon: buildCipherIcon(this.iconsServerUrl, cipher, showFavicons), + accountCreationFieldType: this.focusedFieldData?.accountCreationFieldType, + }; + + if (cipher.type === CipherType.Login) { + inlineMenuData.login = { username: cipher.login.username }; + return inlineMenuData; + } + + if (cipher.type === CipherType.Card) { + inlineMenuData.card = cipher.card.subTitle; + return inlineMenuData; + } + + inlineMenuData.identity = + identityData || this.getIdentityCipherData(cipher, showInlineMenuAccountCreation); + return inlineMenuData; + } + + /** + * Gets the identity data for a cipher based on whether the inline menu is for account creation. + * + * @param cipher - The cipher to get the identity data for + * @param showInlineMenuAccountCreation - Identifies whether the inline menu is for account creation + */ + private getIdentityCipherData( + cipher: CipherView, + showInlineMenuAccountCreation: boolean = false, + ): { fullName: string; username?: string } { + const { firstName, lastName } = cipher.identity; + + let fullName = ""; + if (firstName) { + fullName += firstName; + } + + if (lastName) { + fullName += ` ${lastName}`; + fullName = fullName.trim(); + } + + if ( + !showInlineMenuAccountCreation || + !this.focusedFieldData?.accountCreationFieldType || + this.focusedFieldData.accountCreationFieldType === "password" + ) { + return { fullName }; + } + + return { + fullName, + username: + this.focusedFieldData.accountCreationFieldType === "email" + ? cipher.identity.email + : cipher.identity.username, + }; + } + + /** + * Identifies whether the inline menu is being shown on an account creation field. + */ + private showInlineMenuAccountCreation(): boolean { + if (typeof this.focusedFieldData?.showInlineMenuAccountCreation !== "undefined") { + return this.focusedFieldData?.showInlineMenuAccountCreation; + } + + if (this.focusedFieldData?.filledByCipherType !== CipherType.Login) { + return false; + } + + if (this.cardAndIdentityCiphers) { + return this.inlineMenuCiphers.size === this.cardAndIdentityCiphers.size; + } + + return this.inlineMenuCiphers.size === 0; + } + /** * Gets the currently focused field and closes the inline menu on that tab. */ @@ -926,7 +1097,37 @@ export class OverlayBackground implements OverlayBackgroundInterface { ); } + const previousFocusedFieldData = this.focusedFieldData; this.focusedFieldData = { ...focusedFieldData, tabId: sender.tab.id, frameId: sender.frameId }; + + const accountCreationFieldBlurred = + previousFocusedFieldData?.showInlineMenuAccountCreation && + !this.focusedFieldData.showInlineMenuAccountCreation; + + if (accountCreationFieldBlurred || this.showInlineMenuAccountCreation()) { + void this.updateIdentityCiphersOnLoginField(previousFocusedFieldData); + } + } + + /** + * Triggers an update of populated identity ciphers when a login field is focused. + * + * @param previousFocusedFieldData - The data set of the previously focused field + */ + private async updateIdentityCiphersOnLoginField(previousFocusedFieldData: FocusedFieldData) { + if ( + !previousFocusedFieldData || + !this.isInlineMenuButtonVisible || + (await this.getAuthStatus()) !== AuthenticationStatus.Unlocked + ) { + return; + } + + this.inlineMenuListPort?.postMessage({ + command: "updateAutofillInlineMenuListCiphers", + ciphers: await this.getInlineMenuCipherData(), + showInlineMenuAccountCreation: this.showInlineMenuAccountCreation(), + }); } /** @@ -1116,6 +1317,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { listPageTitle: this.i18nService.translate("bitwardenVault"), unlockYourAccount: this.i18nService.translate("unlockYourAccountToViewAutofillSuggestions"), unlockAccount: this.i18nService.translate("unlockAccount"), + unlockAccountAria: this.i18nService.translate("unlockAccountAria"), fillCredentialsFor: this.i18nService.translate("fillCredentialsFor"), username: this.i18nService.translate("username")?.toLowerCase(), view: this.i18nService.translate("view"), @@ -1123,9 +1325,11 @@ export class OverlayBackground implements OverlayBackgroundInterface { newItem: this.i18nService.translate("newItem"), addNewVaultItem: this.i18nService.translate("addNewVaultItem"), newLogin: this.i18nService.translate("newLogin"), - addNewLoginItem: this.i18nService.translate("addNewLoginItem"), + addNewLoginItem: this.i18nService.translate("addNewLoginItemAria"), newCard: this.i18nService.translate("newCard"), - addNewCardItem: this.i18nService.translate("addNewCardItem"), + addNewCardItem: this.i18nService.translate("addNewCardItemAria"), + newIdentity: this.i18nService.translate("newIdentity"), + addNewIdentityItem: this.i18nService.translate("addNewIdentityItemAria"), cardNumberEndsWith: this.i18nService.translate("cardNumberEndsWith"), }; } @@ -1184,10 +1388,11 @@ export class OverlayBackground implements OverlayBackgroundInterface { * @param addNewCipherType - The type of cipher to add * @param login - The login data captured from the extension message * @param card - The card data captured from the extension message + * @param identity - The identity data captured from the extension message * @param sender - The sender of the extension message */ private async addNewVaultItem( - { addNewCipherType, login, card }: OverlayAddNewItemMessage, + { addNewCipherType, login, card, identity }: OverlayAddNewItemMessage, sender: chrome.runtime.MessageSender, ) { if (!addNewCipherType) { @@ -1198,6 +1403,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { addNewCipherType, login, card, + identity, }); if (cipherView) { @@ -1218,8 +1424,14 @@ export class OverlayBackground implements OverlayBackgroundInterface { * @param addNewCipherType - The type of cipher to add * @param login - The login data captured from the extension message * @param card - The card data captured from the extension message + * @param identity - The identity data captured from the extension message */ - private buildNewVaultItemCipherView({ addNewCipherType, login, card }: OverlayAddNewItemMessage) { + private buildNewVaultItemCipherView({ + addNewCipherType, + login, + card, + identity, + }: OverlayAddNewItemMessage) { if (login && addNewCipherType === CipherType.Login) { return this.buildLoginCipherView(login); } @@ -1227,6 +1439,10 @@ export class OverlayBackground implements OverlayBackgroundInterface { if (card && addNewCipherType === CipherType.Card) { return this.buildCardCipherView(card); } + + if (identity && addNewCipherType === CipherType.Identity) { + return this.buildIdentityCipherView(identity); + } } /** @@ -1275,6 +1491,68 @@ export class OverlayBackground implements OverlayBackgroundInterface { return cipherView; } + /** + * Builds a new identity cipher view with the provided identity data. + * + * @param identity - The identity data captured from the extension message + */ + private buildIdentityCipherView(identity: NewIdentityCipherData) { + const identityView = new IdentityView(); + identityView.title = identity.title || ""; + identityView.firstName = identity.firstName || ""; + identityView.middleName = identity.middleName || ""; + identityView.lastName = identity.lastName || ""; + identityView.address1 = identity.address1 || ""; + identityView.address2 = identity.address2 || ""; + identityView.address3 = identity.address3 || ""; + identityView.city = identity.city || ""; + identityView.state = identity.state || ""; + identityView.postalCode = identity.postalCode || ""; + identityView.country = identity.country || ""; + identityView.company = identity.company || ""; + identityView.phone = identity.phone || ""; + identityView.email = identity.email || ""; + identityView.username = identity.username || ""; + + if (identity.fullName && !identityView.firstName && !identityView.lastName) { + this.buildIdentityNameParts(identity, identityView); + } + + const cipherView = new CipherView(); + cipherView.name = ""; + cipherView.folderId = null; + cipherView.type = CipherType.Identity; + cipherView.identity = identityView; + + return cipherView; + } + + /** + * Splits the identity full name into first, middle, and last name parts. + * + * @param identity - The identity data captured from the extension message + * @param identityView - The identity view to update + */ + private buildIdentityNameParts(identity: NewIdentityCipherData, identityView: IdentityView) { + const fullNameParts = identity.fullName.split(" "); + if (fullNameParts.length === 1) { + identityView.firstName = fullNameParts[0] || ""; + + return; + } + + if (fullNameParts.length === 2) { + identityView.firstName = fullNameParts[0] || ""; + identityView.lastName = fullNameParts[1] || ""; + + return; + } + + identityView.firstName = fullNameParts[0] || ""; + identityView.middleName = fullNameParts[1] || ""; + identityView.lastName = fullNameParts[2] || ""; + } + /** * Updates the property that identifies if a form field set up for the inline menu is currently focused. * @@ -1523,7 +1801,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { Promise.resolve(messageResponse) .then((response) => sendResponse(response)) - .catch(this.logService.error); + .catch((error) => this.logService.error(error)); return true; }; @@ -1598,6 +1876,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { ? AutofillOverlayPort.ListMessageConnector : AutofillOverlayPort.ButtonMessageConnector, filledByCipherType: this.focusedFieldData?.filledByCipherType, + showInlineMenuAccountCreation: this.showInlineMenuAccountCreation(), }); void this.updateInlineMenuPosition( { diff --git a/apps/browser/src/autofill/deprecated/content/autofill-init.deprecated.spec.ts b/apps/browser/src/autofill/deprecated/content/autofill-init.deprecated.spec.ts index 96d5e85ca34..6153a5c926f 100644 --- a/apps/browser/src/autofill/deprecated/content/autofill-init.deprecated.spec.ts +++ b/apps/browser/src/autofill/deprecated/content/autofill-init.deprecated.spec.ts @@ -61,13 +61,10 @@ describe("AutofillInit", () => { autofillInit.init(); jest.advanceTimersByTime(250); - expect(chrome.runtime.sendMessage).toHaveBeenCalledWith( - { - command: "bgCollectPageDetails", - sender: "autofillInit", - }, - expect.any(Function), - ); + expect(chrome.runtime.sendMessage).toHaveBeenCalledWith({ + command: "bgCollectPageDetails", + sender: "autofillInit", + }); }); it("registers a window load listener to collect the page details if the document is not in a `complete` ready state", () => { diff --git a/apps/browser/src/autofill/deprecated/overlay/pages/list/__snapshots__/autofill-overlay-list.deprecated.spec.ts.snap b/apps/browser/src/autofill/deprecated/overlay/pages/list/__snapshots__/autofill-overlay-list.deprecated.spec.ts.snap index 6ee8e737cb5..d11fbd50792 100644 --- a/apps/browser/src/autofill/deprecated/overlay/pages/list/__snapshots__/autofill-overlay-list.deprecated.spec.ts.snap +++ b/apps/browser/src/autofill/deprecated/overlay/pages/list/__snapshots__/autofill-overlay-list.deprecated.spec.ts.snap @@ -506,16 +506,17 @@ exports[`AutofillOverlayList initAutofillOverlayList the overlay with an empty l aria-hidden="true" fill="none" height="17" - viewBox="0 0 16 17" - width="16" + width="17" xmlns="http://www.w3.org/2000/svg" > @@ -523,7 +524,7 @@ exports[`AutofillOverlayList initAutofillOverlayList the overlay with an empty l id="a" > diff --git a/apps/browser/src/autofill/enums/autofill-field.enums.ts b/apps/browser/src/autofill/enums/autofill-field.enums.ts new file mode 100644 index 00000000000..4fd7c0fe88f --- /dev/null +++ b/apps/browser/src/autofill/enums/autofill-field.enums.ts @@ -0,0 +1,29 @@ +export const AutofillFieldQualifier = { + password: "password", + username: "username", + cardholderName: "cardholderName", + cardNumber: "cardNumber", + cardExpirationMonth: "cardExpirationMonth", + cardExpirationYear: "cardExpirationYear", + cardExpirationDate: "cardExpirationDate", + cardCvv: "cardCvv", + identityTitle: "identityTitle", + identityFirstName: "identityFirstName", + identityMiddleName: "identityMiddleName", + identityLastName: "identityLastName", + identityFullName: "identityFullName", + identityAddress1: "identityAddress1", + identityAddress2: "identityAddress2", + identityAddress3: "identityAddress3", + identityCity: "identityCity", + identityState: "identityState", + identityPostalCode: "identityPostalCode", + identityCountry: "identityCountry", + identityCompany: "identityCompany", + identityPhone: "identityPhone", + identityEmail: "identityEmail", + identityUsername: "identityUsername", +} as const; + +export type AutofillFieldQualifierType = + (typeof AutofillFieldQualifier)[keyof typeof AutofillFieldQualifier]; diff --git a/apps/browser/src/autofill/models/autofill-field.ts b/apps/browser/src/autofill/models/autofill-field.ts index 26f01bdeac8..5a95b928994 100644 --- a/apps/browser/src/autofill/models/autofill-field.ts +++ b/apps/browser/src/autofill/models/autofill-field.ts @@ -1,5 +1,7 @@ import { CipherType } from "@bitwarden/common/vault/enums"; +import { AutofillFieldQualifierType } from "../enums/autofill-field.enums"; + /** * Represents a single field that is collected from the page source and is potentially autofilled. */ @@ -110,4 +112,8 @@ export default class AutofillField { checked?: boolean; filledByCipherType?: CipherType; + + showInlineMenuAccountCreation?: boolean; + + fieldQualifier?: AutofillFieldQualifierType; } diff --git a/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts b/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts index 5a00ffbaaa8..090fb7887c9 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts +++ b/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts @@ -7,6 +7,7 @@ type AutofillInlineMenuListMessage = { command: string }; export type UpdateAutofillInlineMenuListCiphersMessage = AutofillInlineMenuListMessage & { ciphers: InlineMenuCipherData[]; + showInlineMenuAccountCreation?: boolean; }; export type InitAutofillInlineMenuListMessage = AutofillInlineMenuListMessage & { @@ -16,6 +17,7 @@ export type InitAutofillInlineMenuListMessage = AutofillInlineMenuListMessage & translations: Record; ciphers?: InlineMenuCipherData[]; filledByCipherType?: CipherType; + showInlineMenuAccountCreation?: boolean; portKey: string; }; diff --git a/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.ts b/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.ts index b8702c74434..ae947415912 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.ts +++ b/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.ts @@ -373,7 +373,7 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte * ensure that the inline menu elements are always present at the bottom of the * body element. */ - private handleBodyElementMutationObserverUpdate = async () => { + private handleBodyElementMutationObserverUpdate = () => { if ( (!this.buttonElement && !this.listElement) || this.isTriggeringExcessiveMutationObserverIterations() @@ -410,17 +410,18 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte return; } + const isInlineMenuListVisible = await this.isInlineMenuListVisible(); if ( !lastChild || (lastChildIsInlineMenuList && secondToLastChildIsInlineMenuButton) || - (lastChildIsInlineMenuButton && !(await this.isInlineMenuListVisible())) + (lastChildIsInlineMenuButton && !isInlineMenuListVisible) ) { return; } if ( (lastChildIsInlineMenuList && !secondToLastChildIsInlineMenuButton) || - (lastChildIsInlineMenuButton && (await this.isInlineMenuListVisible())) + (lastChildIsInlineMenuButton && isInlineMenuListVisible) ) { globalThis.document.body.insertBefore(this.buttonElement, this.listElement); return; diff --git a/apps/browser/src/autofill/overlay/inline-menu/iframe-content/autofill-inline-menu-iframe.service.ts b/apps/browser/src/autofill/overlay/inline-menu/iframe-content/autofill-inline-menu-iframe.service.ts index afa25489305..fd305d23c9a 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/iframe-content/autofill-inline-menu-iframe.service.ts +++ b/apps/browser/src/autofill/overlay/inline-menu/iframe-content/autofill-inline-menu-iframe.service.ts @@ -80,10 +80,11 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe this.defaultIframeAttributes.title = this.iframeTitle; this.iframe = globalThis.document.createElement("iframe"); - this.updateElementStyles(this.iframe, { ...this.iframeStyles, ...this.initStyles }); for (const [attribute, value] of Object.entries(this.defaultIframeAttributes)) { this.iframe.setAttribute(attribute, value); } + this.iframeStyles = { ...this.iframeStyles, ...this.initStyles }; + this.setElementStyles(this.iframe, this.iframeStyles, true); this.iframe.addEventListener(EVENTS.LOAD, this.setupPortMessageListener); if (this.ariaAlert) { @@ -91,6 +92,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe } this.shadow.appendChild(this.iframe); + this.observeIframe(); } /** @@ -143,7 +145,10 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe clearTimeout(this.ariaAlertTimeout); } - this.ariaAlertTimeout = setTimeout(() => this.shadow.appendChild(this.ariaAlertElement), 2000); + this.ariaAlertTimeout = globalThis.setTimeout( + () => this.shadow.appendChild(this.ariaAlertElement), + 2000, + ); } /** @@ -255,7 +260,9 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe return; } - this.clearFadeInTimeout(); + if (this.fadeInTimeout) { + this.handleFadeInInlineMenuIframe(); + } this.updateElementStyles(this.iframe, position); this.announceAriaAlert(); } @@ -325,6 +332,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe private clearFadeInTimeout() { if (this.fadeInTimeout) { clearTimeout(this.fadeInTimeout); + this.fadeInTimeout = null; } } @@ -442,7 +450,10 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe } this.mutationObserverIterations++; - this.mutationObserverIterationsResetTimeout = setTimeout(() => resetCounters(), 2000); + this.mutationObserverIterationsResetTimeout = globalThis.setTimeout( + () => resetCounters(), + 2000, + ); if (this.mutationObserverIterations > 20) { clearTimeout(this.mutationObserverIterationsResetTimeout); diff --git a/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap b/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap index 3b0e84514f2..a8a4d5c4a78 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap +++ b/apps/browser/src/autofill/overlay/inline-menu/pages/list/__snapshots__/autofill-inline-menu-list.spec.ts.snap @@ -13,8 +13,8 @@ exports[`AutofillInlineMenuList initAutofillInlineMenuList the inline menu with class="inline-menu-list-button-container" > + + +`; + +exports[`AutofillInlineMenuList initAutofillInlineMenuList the inline menu with an empty list of ciphers creates the views for the no results inline menu that should be filled by an identity cipher 1`] = ` +
+
+ noItemsToShow +
+
+ +
+
+`; + +exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers for an authenticated user account creation elements creates the inline menu account creation view 1`] = ` +
+
    +
  • +
    + + +
    +
  • +
+
+ + +
+ + +
+`; + +exports[`AutofillInlineMenuList initAutofillInlineMenuList the list of ciphers for an authenticated user creates the views for a list of identity ciphers 1`] = ` +
+
    +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • +
  • +
    + + + + + + + + + + diff --git a/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.spec.ts b/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.spec.ts new file mode 100644 index 00000000000..847283ef5e1 --- /dev/null +++ b/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.spec.ts @@ -0,0 +1,126 @@ +import { CommonModule } from "@angular/common"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { RouterTestingModule } from "@angular/router/testing"; +import { MockProxy, mock } from "jest-mock-extended"; +import { of } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service"; +import { SendView } from "@bitwarden/common/tools/send/models/view/send.view"; +import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; +import { + ButtonModule, + BadgeModule, + DialogService, + IconButtonModule, + ItemModule, + SectionComponent, + SectionHeaderComponent, + ToastService, + TypographyModule, +} from "@bitwarden/components"; + +import { SendListItemsContainerComponent } from "./send-list-items-container.component"; + +describe("SendListItemsContainerComponent", () => { + let component: SendListItemsContainerComponent; + let fixture: ComponentFixture; + let environmentService: MockProxy; + + const openSimpleDialog = jest.fn(); + const showToast = jest.fn(); + const copyToClipboard = jest.fn().mockImplementation(() => {}); + const deleteFn = jest.fn().mockResolvedValue(undefined); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + CommonModule, + RouterTestingModule, + JslibModule, + ItemModule, + ButtonModule, + BadgeModule, + IconButtonModule, + SectionComponent, + SectionHeaderComponent, + TypographyModule, + ], + providers: [ + { provide: EnvironmentService, useValue: environmentService }, + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: LogService, useValue: mock() }, + { provide: PlatformUtilsService, useValue: { copyToClipboard } }, + { provide: SendApiService, useValue: { delete: deleteFn } }, + { provide: ToastService, useValue: { showToast } }, + ], + }) + .overrideProvider(DialogService, { + useValue: { + openSimpleDialog, + }, + }) + .compileComponents(); + + environmentService = mock(); + Object.defineProperty(environmentService, "environment$", { + configurable: true, + get: () => of(new SelfHostedEnvironment({ webVault: "https://example.com" })), + }); + + deleteFn.mockClear(); + showToast.mockClear(); + openSimpleDialog.mockClear(); + copyToClipboard.mockClear(); + + fixture = TestBed.createComponent(SendListItemsContainerComponent); + component = fixture.componentInstance; + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); + + it("should delete a send", async () => { + openSimpleDialog.mockResolvedValue(true); + const send = { id: "123", accessId: "abc", urlB64Key: "xyz" } as SendView; + + await component.deleteSend(send); + + expect(openSimpleDialog).toHaveBeenCalled(); + expect(deleteFn).toHaveBeenCalledWith(send.id); + expect(showToast).toHaveBeenCalledWith({ + variant: "success", + title: null, + message: "deletedSend", + }); + }); + + it("should handle delete send cancellation", async () => { + const send = { id: "123", accessId: "abc", urlB64Key: "xyz" } as SendView; + openSimpleDialog.mockResolvedValue(false); + + await component.deleteSend(send); + + expect(openSimpleDialog).toHaveBeenCalled(); + expect(deleteFn).not.toHaveBeenCalled(); + expect(showToast).not.toHaveBeenCalled(); + }); + + it("should copy send link", async () => { + const send = { id: "123", accessId: "abc", urlB64Key: "xyz" } as SendView; + + await component.copySendLink(send); + + expect(copyToClipboard).toHaveBeenCalledWith("https://example.com/#/send/abc/xyz"); + expect(showToast).toHaveBeenCalledWith({ + variant: "success", + title: null, + message: "valueCopied", + }); + }); +}); diff --git a/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.ts b/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.ts new file mode 100644 index 00000000000..ef7232e97a0 --- /dev/null +++ b/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.ts @@ -0,0 +1,95 @@ +import { CommonModule } from "@angular/common"; +import { Component, Input } from "@angular/core"; +import { RouterLink } from "@angular/router"; +import { firstValueFrom } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; +import { SendView } from "@bitwarden/common/tools/send/models/view/send.view"; +import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; +import { + BadgeModule, + ButtonModule, + DialogService, + IconButtonModule, + ItemModule, + SectionComponent, + SectionHeaderComponent, + ToastService, + TypographyModule, +} from "@bitwarden/components"; + +@Component({ + imports: [ + CommonModule, + ItemModule, + ButtonModule, + BadgeModule, + IconButtonModule, + SectionComponent, + TypographyModule, + JslibModule, + SectionHeaderComponent, + RouterLink, + ], + selector: "app-send-list-items-container", + templateUrl: "send-list-items-container.component.html", + standalone: true, +}) +export class SendListItemsContainerComponent { + sendType = SendType; + /** + * The list of sends to display. + */ + @Input() + sends: SendView[] = []; + + constructor( + protected dialogService: DialogService, + protected environmentService: EnvironmentService, + protected i18nService: I18nService, + protected logService: LogService, + protected platformUtilsService: PlatformUtilsService, + protected sendApiService: SendApiService, + protected toastService: ToastService, + ) {} + + async deleteSend(s: SendView): Promise { + const confirmed = await this.dialogService.openSimpleDialog({ + title: { key: "deleteSend" }, + content: { key: "deleteSendConfirmation" }, + type: "warning", + }); + + if (!confirmed) { + return false; + } + + await this.sendApiService.delete(s.id); + + try { + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("deletedSend"), + }); + } catch (e) { + this.logService.error(e); + } + } + + async copySendLink(s: SendView) { + const env = await firstValueFrom(this.environmentService.environment$); + const link = env.getSendUrl() + s.accessId + "/" + s.urlB64Key; + this.platformUtilsService.copyToClipboard(link); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("valueCopied", this.i18nService.t("sendLink")), + }); + } +} From 96648b48978465ae1a27e8c49239ac1daf930b66 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:16:54 -0400 Subject: [PATCH 04/46] Auth/PM-9603 - AnonLayoutWrapper Dynamic content support (#10216) * PM-9603 - WIP - Untested DefaultAnonLayoutWrapperDataService * PM-9603 - DefaultAnonLayoutWrapperSvc needs constructor * PM-9603 - Good progress on getting storybook setup for the anon-layout-wrapper component - having issues with getting dummy component to display. * PM-9603 - AnonLayoutWrapper Story working with default and dynamic content. * PM-9603 - Tweak verbiage * PM-9603 - Tweak stories; add mdx * PM-9603 - Export AnonLayoutWrapperDataService and DefaultAnonLayoutWrapperDataService from libs/auth and wire up as default implementation in jslib-services.module * PM-9603 - Address PR feedback --- .../src/services/jslib-services.module.ts | 7 + .../anon-layout-wrapper-data.service.ts | 20 ++ .../anon-layout-wrapper.component.ts | 53 +++- .../anon-layout/anon-layout-wrapper.mdx | 28 +++ .../anon-layout-wrapper.stories.ts | 237 ++++++++++++++++++ ...efault-anon-layout-wrapper-data.service.ts | 16 ++ libs/auth/src/angular/index.ts | 2 + 7 files changed, 357 insertions(+), 6 deletions(-) create mode 100644 libs/auth/src/angular/anon-layout/anon-layout-wrapper-data.service.ts create mode 100644 libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx create mode 100644 libs/auth/src/angular/anon-layout/anon-layout-wrapper.stories.ts create mode 100644 libs/auth/src/angular/anon-layout/default-anon-layout-wrapper-data.service.ts diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 3294e597518..8ad1e7d20c6 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -6,6 +6,8 @@ import { DefaultSetPasswordJitService, RegistrationFinishService as RegistrationFinishServiceAbstraction, DefaultRegistrationFinishService, + AnonLayoutWrapperDataService, + DefaultAnonLayoutWrapperDataService, } from "@bitwarden/auth/angular"; import { AuthRequestServiceAbstraction, @@ -1286,6 +1288,11 @@ const safeProviders: SafeProvider[] = [ useClass: RegisterRouteService, deps: [ConfigService], }), + safeProvider({ + provide: AnonLayoutWrapperDataService, + useClass: DefaultAnonLayoutWrapperDataService, + deps: [], + }), safeProvider({ provide: RegistrationFinishServiceAbstraction, useClass: DefaultRegistrationFinishService, diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper-data.service.ts b/libs/auth/src/angular/anon-layout/anon-layout-wrapper-data.service.ts new file mode 100644 index 00000000000..4135e6e0fd6 --- /dev/null +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper-data.service.ts @@ -0,0 +1,20 @@ +import { Observable } from "rxjs"; + +import { AnonLayoutWrapperData } from "./anon-layout-wrapper.component"; + +/** + * A simple data service to allow any child components of the AnonLayoutWrapperComponent to override + * page route data and dynamically control the data fed into the AnonLayoutComponent via the AnonLayoutWrapperComponent. + */ +export abstract class AnonLayoutWrapperDataService { + /** + * + * @param data - The data to set on the AnonLayoutWrapperComponent to feed into the AnonLayoutComponent. + */ + abstract setAnonLayoutWrapperData(data: AnonLayoutWrapperData): void; + + /** + * Reactively gets the current AnonLayoutWrapperData. + */ + abstract anonLayoutWrapperData$(): Observable; +} diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts index 30ef5c1f767..0bedf221e06 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts @@ -6,6 +6,8 @@ import { AnonLayoutComponent } from "@bitwarden/auth/angular"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Icon } from "@bitwarden/components"; +import { AnonLayoutWrapperDataService } from "./anon-layout-wrapper-data.service"; + export interface AnonLayoutWrapperData { pageTitle?: string; pageSubtitle?: string; @@ -30,13 +32,18 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy { private router: Router, private route: ActivatedRoute, private i18nService: I18nService, + private anonLayoutWrapperDataService: AnonLayoutWrapperDataService, ) {} ngOnInit(): void { // Set the initial page data on load - this.setAnonLayoutWrapperData(this.route.snapshot.firstChild?.data); - + this.setAnonLayoutWrapperDataFromRouteData(this.route.snapshot.firstChild?.data); // Listen for page changes and update the page data appropriately + this.listenForPageDataChanges(); + this.listenForServiceDataChanges(); + } + + private listenForPageDataChanges() { this.router.events .pipe( filter((event) => event instanceof NavigationEnd), @@ -46,11 +53,11 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy { takeUntil(this.destroy$), ) .subscribe((firstChildRouteData: Data | null) => { - this.setAnonLayoutWrapperData(firstChildRouteData); + this.setAnonLayoutWrapperDataFromRouteData(firstChildRouteData); }); } - private setAnonLayoutWrapperData(firstChildRouteData: Data | null) { + private setAnonLayoutWrapperDataFromRouteData(firstChildRouteData: Data | null) { if (!firstChildRouteData) { return; } @@ -63,8 +70,42 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy { this.pageSubtitle = this.i18nService.t(firstChildRouteData["pageSubtitle"]); } - this.pageIcon = firstChildRouteData["pageIcon"]; - this.showReadonlyHostname = firstChildRouteData["showReadonlyHostname"]; + if (firstChildRouteData["pageIcon"] !== undefined) { + this.pageIcon = firstChildRouteData["pageIcon"]; + } + + this.showReadonlyHostname = Boolean(firstChildRouteData["showReadonlyHostname"]); + } + + private listenForServiceDataChanges() { + this.anonLayoutWrapperDataService + .anonLayoutWrapperData$() + .pipe(takeUntil(this.destroy$)) + .subscribe((data: AnonLayoutWrapperData) => { + this.setAnonLayoutWrapperData(data); + }); + } + + private setAnonLayoutWrapperData(data: AnonLayoutWrapperData) { + if (!data) { + return; + } + + if (data.pageTitle) { + this.pageTitle = this.i18nService.t(data.pageTitle); + } + + if (data.pageSubtitle) { + this.pageSubtitle = this.i18nService.t(data.pageSubtitle); + } + + if (data.pageIcon) { + this.pageIcon = data.pageIcon; + } + + if (data.showReadonlyHostname) { + this.showReadonlyHostname = data.showReadonlyHostname; + } } private resetPageData() { diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx new file mode 100644 index 00000000000..a218eaa1492 --- /dev/null +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.mdx @@ -0,0 +1,28 @@ +import { Meta, Story, Controls } from "@storybook/addon-docs"; + +import * as stories from "./anon-layout-wrapper.stories"; + + + +# Anon Layout Wrapper + +NOTE: These stories will treat "Light & Dark" mode as "Light" mode. This is done to avoid a bug with +the way that we render the same component twice in the same iframe and how that interacts with the +`router-outlet`. + +## Anon Layout Wrapper Component + +The auth owned `AnonLayoutWrapperComponent` orchestrates routing configuration data and feeds it +into the `AnonLayoutComponent`. See the `Anon Layout` storybook for full documentation on how to use +the `AnonLayoutWrapperComponent`. + +## Default Example with all 3 outlets used + + + +## Dynamic Anon Layout Wrapper Content Example + +This example demonstrates a child component using the `DefaultAnonLayoutWrapperDataService` to +dynamically set the content of the `AnonLayoutWrapperComponent`. + + diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.stories.ts b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.stories.ts new file mode 100644 index 00000000000..80fabe40612 --- /dev/null +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.stories.ts @@ -0,0 +1,237 @@ +import { importProvidersFrom, Component } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; +import { + Meta, + StoryObj, + applicationConfig, + componentWrapperDecorator, + moduleMetadata, +} from "@storybook/angular"; +import { of } from "rxjs"; + +import { ClientType } from "@bitwarden/common/enums"; +import { + EnvironmentService, + Environment, +} from "@bitwarden/common/platform/abstractions/environment.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ThemeType } from "@bitwarden/common/platform/enums"; +import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; +import { ButtonModule } from "@bitwarden/components"; + +import { PreloadedEnglishI18nModule } from "../../../../../apps/web/src/app/core/tests"; +import { LockIcon } from "../icons"; +import { RegistrationCheckEmailIcon } from "../icons/registration-check-email.icon"; + +import { AnonLayoutWrapperDataService } from "./anon-layout-wrapper-data.service"; +import { AnonLayoutWrapperComponent, AnonLayoutWrapperData } from "./anon-layout-wrapper.component"; +import { DefaultAnonLayoutWrapperDataService } from "./default-anon-layout-wrapper-data.service"; + +export default { + title: "Auth/Anon Layout Wrapper", + component: AnonLayoutWrapperComponent, +} as Meta; + +const decorators = (options: { + components: any[]; + routes: Routes; + applicationVersion?: string; + clientType?: ClientType; + hostName?: string; + themeType?: ThemeType; +}) => { + return [ + componentWrapperDecorator( + /** + * Applying a CSS transform makes a `position: fixed` element act like it is `position: relative` + * https://github.com/storybookjs/storybook/issues/8011#issue-490251969 + */ + (story) => { + return /* HTML */ `
    ${story}
    `; + }, + ({ globals }) => { + /** + * avoid a bug with the way that we render the same component twice in the same iframe and how + * that interacts with the router-outlet + */ + const themeOverride = globals["theme"] === "both" ? "light" : globals["theme"]; + return { theme: themeOverride }; + }, + ), + moduleMetadata({ + declarations: options.components, + imports: [RouterModule, ButtonModule], + providers: [ + { + provide: AnonLayoutWrapperDataService, + useClass: DefaultAnonLayoutWrapperDataService, + }, + { + provide: EnvironmentService, + useValue: { + environment$: of({ + getHostname: () => options.hostName || "storybook.bitwarden.com", + } as Partial), + } as Partial, + }, + { + provide: PlatformUtilsService, + useValue: { + getApplicationVersion: () => + Promise.resolve(options.applicationVersion || "FAKE_APP_VERSION"), + getClientType: () => options.clientType || ClientType.Web, + } as Partial, + }, + { + provide: ThemeStateService, + useValue: { + selectedTheme$: of(options.themeType || ThemeType.Light), + } as Partial, + }, + ], + }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot(options.routes)), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), + ]; +}; + +type Story = StoryObj; + +// Default Example + +@Component({ + selector: "bit-default-primary-outlet-example-component", + template: "

    Primary Outlet Example:
    your primary component goes here

    ", +}) +export class DefaultPrimaryOutletExampleComponent {} + +@Component({ + selector: "bit-default-secondary-outlet-example-component", + template: "

    Secondary Outlet Example:
    your secondary component goes here

    ", +}) +export class DefaultSecondaryOutletExampleComponent {} + +@Component({ + selector: "bit-default-env-selector-outlet-example-component", + template: "

    Env Selector Outlet Example:
    your env selector component goes here

    ", +}) +export class DefaultEnvSelectorOutletExampleComponent {} + +export const DefaultContentExample: Story = { + render: (args) => ({ + props: args, + template: "", + }), + decorators: decorators({ + components: [ + DefaultPrimaryOutletExampleComponent, + DefaultSecondaryOutletExampleComponent, + DefaultEnvSelectorOutletExampleComponent, + ], + routes: [ + { + path: "**", + redirectTo: "default-example", + pathMatch: "full", + }, + { + path: "", + component: AnonLayoutWrapperComponent, + children: [ + { + path: "default-example", + data: {}, + children: [ + { + path: "", + component: DefaultPrimaryOutletExampleComponent, + }, + { + path: "", + component: DefaultSecondaryOutletExampleComponent, + outlet: "secondary", + }, + { + path: "", + component: DefaultEnvSelectorOutletExampleComponent, + outlet: "environment-selector", + }, + ], + }, + ], + }, + ], + }), +}; + +// Dynamic Content Example +const initialData: AnonLayoutWrapperData = { + pageTitle: "setAStrongPassword", + pageSubtitle: "finishCreatingYourAccountBySettingAPassword", + pageIcon: LockIcon, +}; + +const changedData: AnonLayoutWrapperData = { + pageTitle: "enterpriseSingleSignOn", + pageSubtitle: "checkYourEmail", + pageIcon: RegistrationCheckEmailIcon, +}; + +@Component({ + selector: "bit-dynamic-content-example-component", + template: ` + + `, +}) +export class DynamicContentExampleComponent { + initialData = true; + + constructor(private anonLayoutWrapperDataService: AnonLayoutWrapperDataService) {} + + toggleData() { + if (this.initialData) { + this.anonLayoutWrapperDataService.setAnonLayoutWrapperData(changedData); + } else { + this.anonLayoutWrapperDataService.setAnonLayoutWrapperData(initialData); + } + + this.initialData = !this.initialData; + } +} + +export const DynamicContentExample: Story = { + render: (args) => ({ + props: args, + template: "", + }), + decorators: decorators({ + components: [DynamicContentExampleComponent], + routes: [ + { + path: "**", + redirectTo: "dynamic-content-example", + pathMatch: "full", + }, + { + path: "", + component: AnonLayoutWrapperComponent, + children: [ + { + path: "dynamic-content-example", + data: initialData, + children: [ + { + path: "", + component: DynamicContentExampleComponent, + }, + ], + }, + ], + }, + ], + }), +}; diff --git a/libs/auth/src/angular/anon-layout/default-anon-layout-wrapper-data.service.ts b/libs/auth/src/angular/anon-layout/default-anon-layout-wrapper-data.service.ts new file mode 100644 index 00000000000..43637d481f7 --- /dev/null +++ b/libs/auth/src/angular/anon-layout/default-anon-layout-wrapper-data.service.ts @@ -0,0 +1,16 @@ +import { Observable, Subject } from "rxjs"; + +import { AnonLayoutWrapperDataService } from "./anon-layout-wrapper-data.service"; +import { AnonLayoutWrapperData } from "./anon-layout-wrapper.component"; + +export class DefaultAnonLayoutWrapperDataService implements AnonLayoutWrapperDataService { + private anonLayoutWrapperDataSubject = new Subject(); + + setAnonLayoutWrapperData(data: AnonLayoutWrapperData): void { + this.anonLayoutWrapperDataSubject.next(data); + } + + anonLayoutWrapperData$(): Observable { + return this.anonLayoutWrapperDataSubject.asObservable(); + } +} diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index f455f42eef4..f6a9ffde55f 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -8,6 +8,8 @@ export * from "./icons"; // anon layout export * from "./anon-layout/anon-layout.component"; export * from "./anon-layout/anon-layout-wrapper.component"; +export * from "./anon-layout/anon-layout-wrapper-data.service"; +export * from "./anon-layout/default-anon-layout-wrapper-data.service"; // fingerprint dialog export * from "./fingerprint-dialog/fingerprint-dialog.component"; From ad26f0890a1d6c80a852a3fde3746675d77e466e Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 25 Jul 2024 23:00:29 +0200 Subject: [PATCH 05/46] [PM-4348] Migrate AuthGuards to functions (#9595) * Migrate auth guards * Fix remaining auth guard migration * Fix unauth guard usage * Add unit tests for auth guard and unauth guard * Remove unused angular DI code * Move auth related logic out fo sm guard * Add tests * Add more tests for unauth guard * Fix incorrect merge --- apps/browser/src/auth/popup/services/index.ts | 1 - .../popup/services/unauth-guard.service.ts | 5 - apps/browser/src/popup/app-routing.module.ts | 74 ++++---- .../src/popup/services/services.module.ts | 8 - apps/desktop/src/app/app-routing.module.ts | 10 +- .../organization-routing.module.ts | 4 +- apps/web/src/app/oss-routing.module.ts | 19 +- .../tools/reports/reports-routing.module.ts | 4 +- .../organizations-routing.module.ts | 6 +- .../providers/providers-routing.module.ts | 8 +- .../app/secrets-manager/guards/sm.guard.ts | 9 - .../app/secrets-manager/sm-routing.module.ts | 6 +- .../src/auth/guards/auth.guard.spec.ts | 177 ++++++++++++++++++ libs/angular/src/auth/guards/auth.guard.ts | 114 +++++------ .../src/auth/guards/unauth.guard.spec.ts | 89 +++++++++ libs/angular/src/auth/guards/unauth.guard.ts | 30 +-- .../src/services/jslib-services.module.ts | 4 - 17 files changed, 392 insertions(+), 176 deletions(-) delete mode 100644 apps/browser/src/auth/popup/services/index.ts delete mode 100644 apps/browser/src/auth/popup/services/unauth-guard.service.ts create mode 100644 libs/angular/src/auth/guards/auth.guard.spec.ts create mode 100644 libs/angular/src/auth/guards/unauth.guard.spec.ts diff --git a/apps/browser/src/auth/popup/services/index.ts b/apps/browser/src/auth/popup/services/index.ts deleted file mode 100644 index 63563f61fd9..00000000000 --- a/apps/browser/src/auth/popup/services/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { UnauthGuardService } from "./unauth-guard.service"; diff --git a/apps/browser/src/auth/popup/services/unauth-guard.service.ts b/apps/browser/src/auth/popup/services/unauth-guard.service.ts deleted file mode 100644 index 0fbb4ac9bae..00000000000 --- a/apps/browser/src/auth/popup/services/unauth-guard.service.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { UnauthGuard as BaseUnauthGuardService } from "@bitwarden/angular/auth/guards"; - -export class UnauthGuardService extends BaseUnauthGuardService { - protected homepage = "tabs/current"; -} diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 57195564c78..47d451cc016 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -2,7 +2,7 @@ import { Injectable, NgModule } from "@angular/core"; import { ActivatedRouteSnapshot, RouteReuseStrategy, RouterModule, Routes } from "@angular/router"; import { - AuthGuard, + authGuard, lockGuard, redirectGuard, tdeDecryptionRequiredGuard, @@ -191,7 +191,7 @@ const routes: Routes = [ { path: "remove-password", component: RemovePasswordComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "remove-password" }, }, { @@ -215,162 +215,162 @@ const routes: Routes = [ { path: "ciphers", component: VaultItemsComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "ciphers" }, }, ...extensionRefreshSwap(ViewComponent, ViewV2Component, { path: "view-cipher", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "view-cipher" }, }), { path: "cipher-password-history", component: PasswordHistoryComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "cipher-password-history" }, }, ...extensionRefreshSwap(AddEditComponent, AddEditV2Component, { path: "add-cipher", - canActivate: [AuthGuard, debounceNavigationGuard()], + canActivate: [authGuard, debounceNavigationGuard()], data: { state: "add-cipher" }, runGuardsAndResolvers: "always", }), ...extensionRefreshSwap(AddEditComponent, AddEditV2Component, { path: "edit-cipher", - canActivate: [AuthGuard, debounceNavigationGuard()], + canActivate: [authGuard, debounceNavigationGuard()], data: { state: "edit-cipher" }, runGuardsAndResolvers: "always", }), { path: "share-cipher", component: ShareComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "share-cipher" }, }, { path: "collections", component: CollectionsComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "collections" }, }, ...extensionRefreshSwap(AttachmentsComponent, AttachmentsV2Component, { path: "attachments", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "attachments" }, }), { path: "generator", component: GeneratorComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "generator" }, }, { path: "generator-history", component: PasswordGeneratorHistoryComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "generator-history" }, }, ...extensionRefreshSwap(ImportBrowserComponent, ImportBrowserV2Component, { path: "import", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "import" }, }), ...extensionRefreshSwap(ExportBrowserComponent, ExportBrowserV2Component, { path: "export", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "export" }, }), ...extensionRefreshSwap(AutofillV1Component, AutofillComponent, { path: "autofill", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "autofill" }, }), { path: "account-security", component: AccountSecurityComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "account-security" }, }, ...extensionRefreshSwap(NotificationsSettingsV1Component, NotificationsSettingsComponent, { path: "notifications", component: NotificationsSettingsV1Component, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "notifications" }, }), ...extensionRefreshSwap(VaultSettingsComponent, VaultSettingsV2Component, { path: "vault-settings", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "vault-settings" }, }), { path: "folders", component: FoldersComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "folders" }, }, { path: "add-folder", component: FolderAddEditComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "add-folder" }, }, { path: "edit-folder", component: FolderAddEditComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "edit-folder" }, }, { path: "sync", component: SyncComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "sync" }, }, ...extensionRefreshSwap(ExcludedDomainsV1Component, ExcludedDomainsComponent, { path: "excluded-domains", component: ExcludedDomainsV1Component, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "excluded-domains" }, }), { path: "premium", component: PremiumComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "premium" }, }, { path: "appearance", component: AppearanceComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "appearance" }, }, ...extensionRefreshSwap(AddEditComponent, AddEditV2Component, { path: "clone-cipher", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "clone-cipher" }, }), { path: "send-type", component: SendTypeComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "send-type" }, }, { path: "add-send", component: SendAddEditComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "add-send" }, }, { path: "edit-send", component: SendAddEditComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "edit-send" }, }, { path: "update-temp-password", component: UpdateTempPasswordComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "update-temp-password" }, }, { @@ -429,12 +429,12 @@ const routes: Routes = [ }, ...extensionRefreshSwap(AboutPageComponent, AboutPageV2Component, { path: "about", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "about" }, }), ...extensionRefreshSwap(MoreFromBitwardenPageComponent, MoreFromBitwardenPageV2Component, { path: "more-from-bitwarden", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "moreFromBitwarden" }, }), ...extensionRefreshSwap(TabsComponent, TabsV2Component, { @@ -449,30 +449,30 @@ const routes: Routes = [ { path: "current", component: CurrentTabComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], canMatch: [extensionRefreshRedirect("/tabs/vault")], data: { state: "tabs_current" }, runGuardsAndResolvers: "always", }, ...extensionRefreshSwap(VaultFilterComponent, VaultV2Component, { path: "vault", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "tabs_vault" }, }), { path: "generator", component: GeneratorComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "tabs_generator" }, }, ...extensionRefreshSwap(SettingsComponent, SettingsV2Component, { path: "settings", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "tabs_settings" }, }), ...extensionRefreshSwap(SendGroupingsComponent, SendV2Component, { path: "send", - canActivate: [AuthGuard], + canActivate: [authGuard], data: { state: "tabs_send" }, }), ], diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 01470f4d115..2c7129db293 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -1,8 +1,6 @@ import { APP_INITIALIZER, NgModule, NgZone } from "@angular/core"; -import { Router } from "@angular/router"; import { Subject, merge, of } from "rxjs"; -import { UnauthGuard as BaseUnauthGuardService } from "@bitwarden/angular/auth/guards"; import { AngularThemingService } from "@bitwarden/angular/platform/services/theming/angular-theming.service"; import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; import { @@ -84,7 +82,6 @@ import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordRepromptService } from "@bitwarden/vault"; -import { UnauthGuardService } from "../../auth/popup/services"; import { AutofillService as AutofillServiceAbstraction } from "../../autofill/services/abstractions/autofill.service"; import AutofillService from "../../autofill/services/autofill.service"; import MainBackground from "../../background/main.background"; @@ -163,11 +160,6 @@ const safeProviders: SafeProvider[] = [ deps: [InitService], multi: true, }), - safeProvider({ - provide: BaseUnauthGuardService, - useClass: UnauthGuardService, - deps: [AuthService, Router], - }), safeProvider({ provide: CryptoFunctionService, useFactory: () => new WebCryptoFunctionService(window), diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index a93299e45a4..2376eb3844b 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -2,7 +2,7 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; import { - AuthGuard, + authGuard, lockGuard, redirectGuard, tdeDecryptionRequiredGuard, @@ -91,7 +91,7 @@ const routes: Routes = [ { path: "vault", component: VaultComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], }, { path: "accessibility-cookie", component: AccessibilityCookieComponent }, { path: "hint", component: HintComponent }, @@ -100,17 +100,17 @@ const routes: Routes = [ { path: "send", component: SendComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], }, { path: "update-temp-password", component: UpdateTempPasswordComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], }, { path: "remove-password", component: RemovePasswordComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { titleId: "removeMasterPassword" }, }, { diff --git a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts index 7427bbb481d..2c8c52efc6a 100644 --- a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; -import { AuthGuard } from "@bitwarden/angular/auth/guards"; +import { authGuard } from "@bitwarden/angular/auth/guards"; import { featureFlaggedRoute } from "@bitwarden/angular/platform/utils/feature-flagged-route"; import { canAccessOrgAdmin, @@ -26,7 +26,7 @@ const routes: Routes = [ { path: ":organizationId", component: OrganizationLayoutComponent, - canActivate: [deepLinkGuard(), AuthGuard, organizationPermissionsGuard(canAccessOrgAdmin)], + canActivate: [deepLinkGuard(), authGuard, organizationPermissionsGuard(canAccessOrgAdmin)], children: [ { path: "", diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 034f65366aa..65414317cbc 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -2,11 +2,10 @@ import { NgModule } from "@angular/core"; import { Route, RouterModule, Routes } from "@angular/router"; import { - AuthGuard, + authGuard, lockGuard, redirectGuard, tdeDecryptionRequiredGuard, - UnauthGuard, unauthGuardFn, } from "@bitwarden/angular/auth/guards"; import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard"; @@ -105,7 +104,7 @@ const routes: Routes = [ { path: "register", component: TrialInitiationComponent, - canActivate: [UnauthGuard], + canActivate: [unauthGuardFn()], data: { titleId: "createAccount" } satisfies DataProperties, }, { @@ -135,13 +134,13 @@ const routes: Routes = [ { path: "verify-recover-delete-org", component: VerifyRecoverDeleteOrgComponent, - canActivate: [UnauthGuard], + canActivate: [unauthGuardFn()], data: { titleId: "deleteOrganization" }, }, { path: "verify-recover-delete-provider", component: VerifyRecoverDeleteProviderComponent, - canActivate: [UnauthGuard], + canActivate: [unauthGuardFn()], data: { titleId: "deleteAccount" } satisfies DataProperties, }, { @@ -152,13 +151,13 @@ const routes: Routes = [ { path: "update-temp-password", component: UpdateTempPasswordComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { titleId: "updateTempPassword" } satisfies DataProperties, }, { path: "update-password", component: UpdatePasswordComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { titleId: "updatePassword" } satisfies DataProperties, }, { @@ -395,7 +394,7 @@ const routes: Routes = [ { path: "remove-password", component: RemovePasswordComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], data: { pageTitle: "removeMasterPassword", titleId: "removeMasterPassword", @@ -406,7 +405,7 @@ const routes: Routes = [ { path: "", component: UserLayoutComponent, - canActivate: [deepLinkGuard(), AuthGuard], + canActivate: [deepLinkGuard(), authGuard], children: [ { path: "vault", @@ -486,7 +485,7 @@ const routes: Routes = [ }, { path: "tools", - canActivate: [AuthGuard], + canActivate: [authGuard], children: [ { path: "", pathMatch: "full", redirectTo: "generator" }, { diff --git a/apps/web/src/app/tools/reports/reports-routing.module.ts b/apps/web/src/app/tools/reports/reports-routing.module.ts index 0733a57564b..cad6586bb82 100644 --- a/apps/web/src/app/tools/reports/reports-routing.module.ts +++ b/apps/web/src/app/tools/reports/reports-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; -import { AuthGuard } from "@bitwarden/angular/auth/guards"; +import { authGuard } from "@bitwarden/angular/auth/guards"; import { hasPremiumGuard } from "../../core/guards/has-premium.guard"; @@ -18,7 +18,7 @@ const routes: Routes = [ { path: "", component: ReportsLayoutComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], children: [ { path: "", diff --git a/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts b/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts index 413ced840d7..8e5860833c5 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; -import { AuthGuard } from "@bitwarden/angular/auth/guards"; +import { authGuard } from "@bitwarden/angular/auth/guards"; import { canAccessSettingsTab } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { isEnterpriseOrgGuard } from "@bitwarden/web-vault/app/admin-console/organizations/guards/is-enterprise-org.guard"; import { organizationPermissionsGuard } from "@bitwarden/web-vault/app/admin-console/organizations/guards/org-permissions.guard"; @@ -16,7 +16,7 @@ const routes: Routes = [ { path: "organizations/:organizationId", component: OrganizationLayoutComponent, - canActivate: [AuthGuard, organizationPermissionsGuard()], + canActivate: [authGuard, organizationPermissionsGuard()], children: [ { path: "settings", @@ -61,7 +61,7 @@ const routes: Routes = [ }, { path: "reporting/reports", - canActivate: [AuthGuard, organizationPermissionsGuard((org) => org.canAccessReports)], + canActivate: [authGuard, organizationPermissionsGuard((org) => org.canAccessReports)], children: [ { path: "member-access-report", diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-routing.module.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-routing.module.ts index f2e890afe22..21fa863d2a9 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-routing.module.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; -import { AuthGuard } from "@bitwarden/angular/auth/guards"; +import { authGuard } from "@bitwarden/angular/auth/guards"; import { featureFlaggedRoute } from "@bitwarden/angular/platform/utils/feature-flagged-route"; import { AnonLayoutWrapperComponent } from "@bitwarden/auth/angular"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; @@ -32,12 +32,12 @@ import { SetupComponent } from "./setup/setup.component"; const routes: Routes = [ { path: "", - canActivate: [AuthGuard], + canActivate: [authGuard], component: UserLayoutComponent, children: [ { path: "", - canActivate: [AuthGuard], + canActivate: [authGuard], component: ProvidersComponent, data: { titleId: "providers" }, }, @@ -70,7 +70,7 @@ const routes: Routes = [ }, { path: "", - canActivate: [AuthGuard], + canActivate: [authGuard], children: [ { path: "setup", diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/guards/sm.guard.ts b/bitwarden_license/bit-web/src/app/secrets-manager/guards/sm.guard.ts index d8cda60d9bd..2a36bf1cbbc 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/guards/sm.guard.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/guards/sm.guard.ts @@ -6,10 +6,7 @@ import { RouterStateSnapshot, } from "@angular/router"; -import { AuthGuard } from "@bitwarden/angular/auth/guards"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; /** @@ -20,19 +17,13 @@ export const canActivateSM: CanActivateFn = async ( state: RouterStateSnapshot, ) => { const syncService = inject(SyncService); - const authService = inject(AuthService); const orgService = inject(OrganizationService); - const authGuard = inject(AuthGuard); /** Workaround to avoid service initialization race condition. */ if ((await syncService.getLastSync()) == null) { await syncService.fullSync(false); } - if ((await authService.getAuthStatus()) !== AuthenticationStatus.Unlocked) { - return authGuard.canActivate(route, state); - } - const orgs = await orgService.getAll(); const smOrg = orgs.find((o) => o.canAccessSecretsManager); if (smOrg) { diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/sm-routing.module.ts b/bitwarden_license/bit-web/src/app/secrets-manager/sm-routing.module.ts index 00ec259a124..bcc4869c896 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/sm-routing.module.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/sm-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; -import { AuthGuard } from "@bitwarden/angular/auth/guards"; +import { authGuard } from "@bitwarden/angular/auth/guards"; import { organizationEnabledGuard } from "./guards/sm-org-enabled.guard"; import { canActivateSM } from "./guards/sm.guard"; @@ -22,14 +22,14 @@ const routes: Routes = [ children: [ { path: "", - canActivate: [canActivateSM], + canActivate: [authGuard, canActivateSM], pathMatch: "full", children: [], }, { path: ":organizationId", component: LayoutComponent, - canActivate: [AuthGuard], + canActivate: [authGuard], children: [ { path: "", diff --git a/libs/angular/src/auth/guards/auth.guard.spec.ts b/libs/angular/src/auth/guards/auth.guard.spec.ts new file mode 100644 index 00000000000..8d024b6b2b1 --- /dev/null +++ b/libs/angular/src/auth/guards/auth.guard.spec.ts @@ -0,0 +1,177 @@ +import { TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { RouterTestingModule } from "@angular/router/testing"; +import { MockProxy, mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; + +import { EmptyComponent } from "@bitwarden/angular/platform/guard/feature-flag.guard.spec"; +import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; +import { MasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; +import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { UserId } from "@bitwarden/common/types/guid"; + +import { authGuard } from "./auth.guard"; + +describe("AuthGuard", () => { + const setup = ( + authStatus: AuthenticationStatus, + forceSetPasswordReason: ForceSetPasswordReason, + keyConnectorServiceRequiresAccountConversion: boolean = false, + ) => { + const authService: MockProxy = mock(); + authService.getAuthStatus.mockResolvedValue(authStatus); + const messagingService: MockProxy = mock(); + const keyConnectorService: MockProxy = mock(); + keyConnectorService.getConvertAccountRequired.mockResolvedValue( + keyConnectorServiceRequiresAccountConversion, + ); + const accountService: MockProxy = mock(); + const activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>(null); + accountService.activeAccount$ = activeAccountSubject; + activeAccountSubject.next( + Object.assign( + { + name: "Test User 1", + email: "test@email.com", + emailVerified: true, + } as AccountInfo, + { id: "test-id" as UserId }, + ), + ); + + const forceSetPasswordReasonSubject = new BehaviorSubject( + forceSetPasswordReason, + ); + const masterPasswordService: MockProxy = + mock(); + masterPasswordService.forceSetPasswordReason$.mockReturnValue(forceSetPasswordReasonSubject); + + const testBed = TestBed.configureTestingModule({ + imports: [ + RouterTestingModule.withRoutes([ + { path: "", component: EmptyComponent }, + { path: "guarded-route", component: EmptyComponent, canActivate: [authGuard] }, + { path: "lock", component: EmptyComponent }, + { path: "set-password", component: EmptyComponent }, + { path: "update-temp-password", component: EmptyComponent }, + { path: "remove-password", component: EmptyComponent }, + ]), + ], + providers: [ + { provide: AuthService, useValue: authService }, + { provide: MessagingService, useValue: messagingService }, + { provide: KeyConnectorService, useValue: keyConnectorService }, + { provide: AccountService, useValue: accountService }, + { provide: MasterPasswordServiceAbstraction, useValue: masterPasswordService }, + ], + }); + + return { + router: testBed.inject(Router), + }; + }; + + it("should be created", () => { + const { router } = setup(AuthenticationStatus.LoggedOut, ForceSetPasswordReason.None); + expect(router).toBeTruthy(); + }); + + it("should return allow access to the guarded route when user is logged in & unlocked", async () => { + const { router } = setup(AuthenticationStatus.Unlocked, ForceSetPasswordReason.None); + + await router.navigate(["guarded-route"]); + expect(router.url).toBe("/guarded-route"); + }); + + it("should redirect to /lock when user is locked", async () => { + const { router } = setup(AuthenticationStatus.Locked, ForceSetPasswordReason.None); + + await router.navigate(["guarded-route"]); + expect(router.url).toContain("/lock"); + }); + + it("should redirect to / when user is logged out", async () => { + const { router } = setup(AuthenticationStatus.LoggedOut, ForceSetPasswordReason.None); + + await router.navigate(["guarded-route"]); + expect(router.url).toBe("/"); + }); + + it("should redirect to /remove-password if keyconnector service requires account conversion", async () => { + const { router } = setup(AuthenticationStatus.Unlocked, ForceSetPasswordReason.None, true); + + await router.navigate(["guarded-route"]); + expect(router.url).toBe("/remove-password"); + }); + + it("should redirect to set-password when user is TDE user without password and has password reset permission", async () => { + const { router } = setup( + AuthenticationStatus.Unlocked, + ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission, + ); + + await router.navigate(["guarded-route"]); + expect(router.url).toContain("/set-password"); + }); + + it("should redirect to update-temp-password when user has force set password reason", async () => { + const { router } = setup( + AuthenticationStatus.Unlocked, + ForceSetPasswordReason.AdminForcePasswordReset, + ); + + await router.navigate(["guarded-route"]); + expect(router.url).toContain("/update-temp-password"); + }); + + it("should redirect to update-temp-password when user has weak password", async () => { + const { router } = setup( + AuthenticationStatus.Unlocked, + ForceSetPasswordReason.WeakMasterPassword, + ); + + await router.navigate(["guarded-route"]); + expect(router.url).toContain("/update-temp-password"); + }); + + it("should allow navigation to set-password when the user is unlocked, is a TDE user without password, and has password reset permission", async () => { + const { router } = setup( + AuthenticationStatus.Unlocked, + ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission, + ); + + await router.navigate(["/set-password"]); + expect(router.url).toContain("/set-password"); + }); + + it("should allow navigation to update-temp-password when the user is unlocked and has admin force password reset permission", async () => { + const { router } = setup( + AuthenticationStatus.Unlocked, + ForceSetPasswordReason.AdminForcePasswordReset, + ); + + await router.navigate(["/update-temp-password"]); + expect(router.url).toContain("/update-temp-password"); + }); + + it("should allow navigation to update-temp-password when the user is unlocked and has weak password", async () => { + const { router } = setup( + AuthenticationStatus.Unlocked, + ForceSetPasswordReason.WeakMasterPassword, + ); + + await router.navigate(["/update-temp-password"]); + expect(router.url).toContain("/update-temp-password"); + }); + + it("should allow navigation to remove-password when the user is unlocked and has 'none' password reset permission", async () => { + const { router } = setup(AuthenticationStatus.Unlocked, ForceSetPasswordReason.None); + + await router.navigate(["/remove-password"]); + expect(router.url).toContain("/remove-password"); + }); +}); diff --git a/libs/angular/src/auth/guards/auth.guard.ts b/libs/angular/src/auth/guards/auth.guard.ts index b8e37d0af36..b54f114d3d4 100644 --- a/libs/angular/src/auth/guards/auth.guard.ts +++ b/libs/angular/src/auth/guards/auth.guard.ts @@ -1,5 +1,11 @@ -import { Injectable } from "@angular/core"; -import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from "@angular/router"; +import { inject } from "@angular/core"; +import { + ActivatedRouteSnapshot, + CanActivateFn, + Router, + RouterStateSnapshot, + UrlTree, +} from "@angular/router"; import { firstValueFrom } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -10,59 +16,57 @@ import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authenticatio import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -@Injectable() -export class AuthGuard implements CanActivate { - constructor( - private authService: AuthService, - private router: Router, - private messagingService: MessagingService, - private keyConnectorService: KeyConnectorService, - private accountService: AccountService, - private masterPasswordService: MasterPasswordServiceAbstraction, - ) {} +export const authGuard: CanActivateFn = async ( + route: ActivatedRouteSnapshot, + routerState: RouterStateSnapshot, +): Promise => { + const authService = inject(AuthService); + const router = inject(Router); + const messagingService = inject(MessagingService); + const keyConnectorService = inject(KeyConnectorService); + const accountService = inject(AccountService); + const masterPasswordService = inject(MasterPasswordServiceAbstraction); - async canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) { - const authStatus = await this.authService.getAuthStatus(); + const authStatus = await authService.getAuthStatus(); - if (authStatus === AuthenticationStatus.LoggedOut) { - this.messagingService.send("authBlocked", { url: routerState.url }); - return false; - } - - if (authStatus === AuthenticationStatus.Locked) { - if (routerState != null) { - this.messagingService.send("lockedUrl", { url: routerState.url }); - } - return this.router.createUrlTree(["lock"], { queryParams: { promptBiometric: true } }); - } - - if ( - !routerState.url.includes("remove-password") && - (await this.keyConnectorService.getConvertAccountRequired()) - ) { - return this.router.createUrlTree(["/remove-password"]); - } - - const userId = (await firstValueFrom(this.accountService.activeAccount$)).id; - const forceSetPasswordReason = await firstValueFrom( - this.masterPasswordService.forceSetPasswordReason$(userId), - ); - - if ( - forceSetPasswordReason === - ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission && - !routerState.url.includes("set-password") - ) { - return this.router.createUrlTree(["/set-password"]); - } - - if ( - forceSetPasswordReason !== ForceSetPasswordReason.None && - !routerState.url.includes("update-temp-password") - ) { - return this.router.createUrlTree(["/update-temp-password"]); - } - - return true; + if (authStatus === AuthenticationStatus.LoggedOut) { + messagingService.send("authBlocked", { url: routerState.url }); + return false; } -} + + if (authStatus === AuthenticationStatus.Locked) { + if (routerState != null) { + messagingService.send("lockedUrl", { url: routerState.url }); + } + return router.createUrlTree(["lock"], { queryParams: { promptBiometric: true } }); + } + + if ( + !routerState.url.includes("remove-password") && + (await keyConnectorService.getConvertAccountRequired()) + ) { + return router.createUrlTree(["/remove-password"]); + } + + const userId = (await firstValueFrom(accountService.activeAccount$)).id; + const forceSetPasswordReason = await firstValueFrom( + masterPasswordService.forceSetPasswordReason$(userId), + ); + + if ( + forceSetPasswordReason === + ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission && + !routerState.url.includes("set-password") + ) { + return router.createUrlTree(["/set-password"]); + } + + if ( + forceSetPasswordReason !== ForceSetPasswordReason.None && + !routerState.url.includes("update-temp-password") + ) { + return router.createUrlTree(["/update-temp-password"]); + } + + return true; +}; diff --git a/libs/angular/src/auth/guards/unauth.guard.spec.ts b/libs/angular/src/auth/guards/unauth.guard.spec.ts new file mode 100644 index 00000000000..6d8619f4d43 --- /dev/null +++ b/libs/angular/src/auth/guards/unauth.guard.spec.ts @@ -0,0 +1,89 @@ +import { TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { RouterTestingModule } from "@angular/router/testing"; +import { MockProxy, mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; + +import { EmptyComponent } from "@bitwarden/angular/platform/guard/feature-flag.guard.spec"; +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; + +import { unauthGuardFn } from "./unauth.guard"; + +describe("UnauthGuard", () => { + const setup = (authStatus: AuthenticationStatus) => { + const authService: MockProxy = mock(); + authService.getAuthStatus.mockResolvedValue(authStatus); + const activeAccountStatusObservable = new BehaviorSubject(authStatus); + authService.activeAccountStatus$ = activeAccountStatusObservable; + + const testBed = TestBed.configureTestingModule({ + imports: [ + RouterTestingModule.withRoutes([ + { path: "", component: EmptyComponent }, + { + path: "unauth-guarded-route", + component: EmptyComponent, + canActivate: [unauthGuardFn()], + }, + { path: "vault", component: EmptyComponent }, + { path: "lock", component: EmptyComponent }, + { path: "testhomepage", component: EmptyComponent }, + { path: "testlocked", component: EmptyComponent }, + { + path: "testOverrides", + component: EmptyComponent, + canActivate: [ + unauthGuardFn({ homepage: () => "/testhomepage", locked: "/testlocked" }), + ], + }, + ]), + ], + providers: [{ provide: AuthService, useValue: authService }], + }); + + return { + router: testBed.inject(Router), + }; + }; + + it("should be created", () => { + const { router } = setup(AuthenticationStatus.LoggedOut); + expect(router).toBeTruthy(); + }); + + it("should redirect to /vault for guarded routes when logged in and unlocked", async () => { + const { router } = setup(AuthenticationStatus.Unlocked); + + await router.navigateByUrl("unauth-guarded-route"); + expect(router.url).toBe("/vault"); + }); + + it("should allow access to guarded routes when logged out", async () => { + const { router } = setup(AuthenticationStatus.LoggedOut); + + await router.navigateByUrl("unauth-guarded-route"); + expect(router.url).toBe("/unauth-guarded-route"); + }); + + it("should redirect to /lock for guarded routes when locked", async () => { + const { router } = setup(AuthenticationStatus.Locked); + + await router.navigateByUrl("unauth-guarded-route"); + expect(router.url).toBe("/lock"); + }); + + it("should redirect to /testhomepage for guarded routes when testOverrides are provided and the account is unlocked", async () => { + const { router } = setup(AuthenticationStatus.Unlocked); + + await router.navigateByUrl("testOverrides"); + expect(router.url).toBe("/testhomepage"); + }); + + it("should redirect to /testlocked for guarded routes when testOverrides are provided and the account is locked", async () => { + const { router } = setup(AuthenticationStatus.Locked); + + await router.navigateByUrl("testOverrides"); + expect(router.url).toBe("/testlocked"); + }); +}); diff --git a/libs/angular/src/auth/guards/unauth.guard.ts b/libs/angular/src/auth/guards/unauth.guard.ts index 9e1bca98ca4..f96668773ef 100644 --- a/libs/angular/src/auth/guards/unauth.guard.ts +++ b/libs/angular/src/auth/guards/unauth.guard.ts @@ -1,36 +1,10 @@ -import { Injectable, inject } from "@angular/core"; -import { CanActivate, CanActivateFn, Router, UrlTree } from "@angular/router"; +import { inject } from "@angular/core"; +import { CanActivateFn, Router, UrlTree } from "@angular/router"; import { Observable, map } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; -/** - * @deprecated use unauthGuardFn function instead - */ -@Injectable() -export class UnauthGuard implements CanActivate { - protected homepage = "vault"; - constructor( - private authService: AuthService, - private router: Router, - ) {} - - async canActivate() { - const authStatus = await this.authService.getAuthStatus(); - - if (authStatus === AuthenticationStatus.LoggedOut) { - return true; - } - - if (authStatus === AuthenticationStatus.Locked) { - return this.router.createUrlTree(["lock"]); - } - - return this.router.createUrlTree([this.homepage]); - } -} - type UnauthRoutes = { homepage: () => string; locked: string; diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 8ad1e7d20c6..a0fec2ad05f 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -269,8 +269,6 @@ import { IndividualVaultExportServiceAbstraction, } from "@bitwarden/vault-export-core"; -import { AuthGuard } from "../auth/guards/auth.guard"; -import { UnauthGuard } from "../auth/guards/unauth.guard"; import { FormValidationErrorsService as FormValidationErrorsServiceAbstraction } from "../platform/abstractions/form-validation-errors.service"; import { FormValidationErrorsService } from "../platform/services/form-validation-errors.service"; import { LoggingErrorHandler } from "../platform/services/logging-error-handler"; @@ -306,8 +304,6 @@ import { ModalService } from "./modal.service"; * If you need help please ask for it, do NOT change the type of this array. */ const safeProviders: SafeProvider[] = [ - safeProvider(AuthGuard), - safeProvider(UnauthGuard), safeProvider(ModalService), safeProvider(PasswordRepromptService), safeProvider({ provide: WINDOW, useValue: window }), From c5c8c45bab33d11c40550657d04f4950b8d51679 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Fri, 26 Jul 2024 07:46:11 +1000 Subject: [PATCH 06/46] [AC-2924] Remove GroupsComponentRefactor flag (#10259) * Remove feature flag and old component --- .../manage/groups.component.html | 175 ++++++------ .../organizations/manage/groups.component.ts | 251 +++++------------ .../manage/new-groups.component.html | 109 -------- .../manage/new-groups.component.ts | 255 ------------------ .../organization-routing.module.ts | 24 +- .../organizations/organization.module.ts | 3 +- libs/common/src/enums/feature-flag.enum.ts | 2 - 7 files changed, 167 insertions(+), 652 deletions(-) delete mode 100644 apps/web/src/app/admin-console/organizations/manage/new-groups.component.html delete mode 100644 apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts diff --git a/apps/web/src/app/admin-console/organizations/manage/groups.component.html b/apps/web/src/app/admin-console/organizations/manage/groups.component.html index 2ebafb38fc9..1254d48cc76 100644 --- a/apps/web/src/app/admin-console/organizations/manage/groups.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/groups.component.html @@ -1,7 +1,7 @@ + +

    {{ "noGroupsInList" | i18n }}

    + + + + + + + + + + {{ "name" | i18n }} + {{ "collections" | i18n }} + + - - + + + + + + + + + + + - - - -
    - - - - - - - - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + + + - diff --git a/apps/web/src/app/admin-console/organizations/manage/groups.component.ts b/apps/web/src/app/admin-console/organizations/manage/groups.component.ts index 7c86ac28498..dfb6f349ebd 100644 --- a/apps/web/src/app/admin-console/organizations/manage/groups.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/groups.component.ts @@ -1,4 +1,6 @@ -import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; +import { Component } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { FormControl } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; import { BehaviorSubject, @@ -7,21 +9,15 @@ import { from, lastValueFrom, map, - Subject, switchMap, - takeUntil, tap, } from "rxjs"; -import { first } from "rxjs/operators"; +import { debounceTime, first } from "rxjs/operators"; -import { SearchPipe } from "@bitwarden/angular/pipes/search.pipe"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; import { CollectionData } from "@bitwarden/common/vault/models/data/collection.data"; import { Collection } from "@bitwarden/common/vault/models/domain/collection"; @@ -30,7 +26,7 @@ import { CollectionResponse, } from "@bitwarden/common/vault/models/response/collection.response"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, TableDataSource, ToastService } from "@bitwarden/components"; import { InternalGroupService as GroupService, GroupView } from "../core"; @@ -40,21 +36,7 @@ import { openGroupAddEditDialog, } from "./group-add-edit.component"; -type CollectionViewMap = { - [id: string]: CollectionView; -}; - type GroupDetailsRow = { - /** - * Group Id (used for searching) - */ - id: string; - - /** - * Group name (used for searching) - */ - name: string; - /** * Details used for displaying group information */ @@ -72,59 +54,38 @@ type GroupDetailsRow = { }; /** - * @deprecated To be replaced with NewGroupsComponent which significantly refactors this component. - * The GroupsComponentRefactor flag switches between the old and new components; this component will be removed when - * the feature flag is removed. + * Custom filter predicate that filters the groups table by id and name only. + * This is required because the default implementation searches by all properties, which can unintentionally match + * with members' names (who are assigned to the group) or collection names (which the group has access to). */ +const groupsFilter = (filter: string) => { + const transformedFilter = filter.trim().toLowerCase(); + return (data: GroupDetailsRow) => { + const group = data.details; + + return ( + group.id.toLowerCase().indexOf(transformedFilter) != -1 || + group.name.toLowerCase().indexOf(transformedFilter) != -1 + ); + }; +}; + @Component({ - selector: "app-org-groups", templateUrl: "groups.component.html", }) -export class GroupsComponent implements OnInit, OnDestroy { - @ViewChild("addEdit", { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef; - @ViewChild("usersTemplate", { read: ViewContainerRef, static: true }) - usersModalRef: ViewContainerRef; - +export class GroupsComponent { loading = true; organizationId: string; - groups: GroupDetailsRow[]; - protected didScroll = false; - protected pageSize = 100; + protected dataSource = new TableDataSource(); + protected searchControl = new FormControl(""); + + // Fixed sizes used for cdkVirtualScroll + protected rowHeight = 46; + protected rowHeightClass = `tw-h-[46px]`; + protected ModalTabType = GroupAddEditTabType; - - private pagedGroupsCount = 0; - private pagedGroups: GroupDetailsRow[]; - private searchedGroups: GroupDetailsRow[]; - private _searchText$ = new BehaviorSubject(""); - private destroy$ = new Subject(); private refreshGroups$ = new BehaviorSubject(null); - private isSearching: boolean = false; - - get searchText() { - return this._searchText$.value; - } - set searchText(value: string) { - this._searchText$.next(value); - // Manually update as we are not using the search pipe in the template - this.updateSearchedGroups(); - } - - /** - * The list of groups that should be visible in the table. - * This is needed as there are two modes (paging/searching) and - * we need a reference to the currently visible groups for - * the Select All checkbox - */ - get visibleGroups(): GroupDetailsRow[] { - if (this.isPaging()) { - return this.pagedGroups; - } - if (this.isSearching) { - return this.searchedGroups; - } - return this.groups; - } constructor( private apiService: ApiService, @@ -132,14 +93,10 @@ export class GroupsComponent implements OnInit, OnDestroy { private route: ActivatedRoute, private i18nService: I18nService, private dialogService: DialogService, - private platformUtilsService: PlatformUtilsService, - private searchService: SearchService, private logService: LogService, private collectionService: CollectionService, - private searchPipe: SearchPipe, - ) {} - - async ngOnInit() { + private toastService: ToastService, + ) { this.route.params .pipe( tap((params) => (this.organizationId = params.organizationId)), @@ -156,68 +113,31 @@ export class GroupsComponent implements OnInit, OnDestroy { ]), ), map(([collectionMap, groups]) => { - return groups - .sort(Utils.getSortFunction(this.i18nService, "name")) - .map((g) => ({ - id: g.id, - name: g.name, - details: g, - checked: false, - collectionNames: g.collections - .map((c) => collectionMap[c.id]?.name) - .sort(this.i18nService.collator?.compare), - })); + return groups.map((g) => ({ + id: g.id, + name: g.name, + details: g, + checked: false, + collectionNames: g.collections + .map((c) => collectionMap[c.id]?.name) + .sort(this.i18nService.collator?.compare), + })); }), - takeUntil(this.destroy$), + takeUntilDestroyed(), ) .subscribe((groups) => { - this.groups = groups; - this.resetPaging(); - this.updateSearchedGroups(); + this.dataSource.data = groups; this.loading = false; }); - this.route.queryParams - .pipe( - first(), - concatMap(async (qParams) => { - this.searchText = qParams.search; - }), - takeUntil(this.destroy$), - ) - .subscribe(); + // Connect the search input to the table dataSource filter input + this.searchControl.valueChanges + .pipe(debounceTime(200), takeUntilDestroyed()) + .subscribe((v) => (this.dataSource.filter = groupsFilter(v))); - this._searchText$ - .pipe( - switchMap((searchText) => this.searchService.isSearchable(searchText)), - takeUntil(this.destroy$), - ) - .subscribe((isSearchable) => { - this.isSearching = isSearchable; - }); - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } - - loadMore() { - if (!this.groups || this.groups.length <= this.pageSize) { - return; - } - const pagedLength = this.pagedGroups.length; - let pagedSize = this.pageSize; - if (pagedLength === 0 && this.pagedGroupsCount > this.pageSize) { - pagedSize = this.pagedGroupsCount; - } - if (this.groups.length > pagedLength) { - this.pagedGroups = this.pagedGroups.concat( - this.groups.slice(pagedLength, pagedLength + pagedSize), - ); - } - this.pagedGroupsCount = this.pagedGroups.length; - this.didScroll = this.pagedGroups.length > this.pageSize; + this.route.queryParams.pipe(first(), takeUntilDestroyed()).subscribe((qParams) => { + this.searchControl.setValue(qParams.search); + }); } async edit( @@ -237,14 +157,12 @@ export class GroupsComponent implements OnInit, OnDestroy { if (result == GroupAddEditDialogResultType.Saved) { this.refreshGroups$.next(); } else if (result == GroupAddEditDialogResultType.Deleted) { - this.removeGroup(group.details.id); + this.removeGroup(group); } } - add() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.edit(null); + async add() { + await this.edit(null); } async delete(groupRow: GroupDetailsRow) { @@ -259,19 +177,19 @@ export class GroupsComponent implements OnInit, OnDestroy { try { await this.groupService.delete(this.organizationId, groupRow.details.id); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("deletedGroupId", groupRow.details.name), - ); - this.removeGroup(groupRow.details.id); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("deletedGroupId", groupRow.details.name), + }); + this.removeGroup(groupRow); } catch (e) { this.logService.error(e); } } async deleteAllSelected() { - const groupsToDelete = this.groups.filter((g) => g.checked); + const groupsToDelete = this.dataSource.data.filter((g) => g.checked); if (groupsToDelete.length == 0) { return; @@ -295,46 +213,31 @@ export class GroupsComponent implements OnInit, OnDestroy { this.organizationId, groupsToDelete.map((g) => g.details.id), ); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("deletedManyGroups", groupsToDelete.length.toString()), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("deletedManyGroups", groupsToDelete.length.toString()), + }); - groupsToDelete.forEach((g) => this.removeGroup(g.details.id)); + groupsToDelete.forEach((g) => this.removeGroup(g)); } catch (e) { this.logService.error(e); } } - resetPaging() { - this.pagedGroups = []; - this.loadMore(); - } - check(groupRow: GroupDetailsRow) { groupRow.checked = !groupRow.checked; } toggleAllVisible(event: Event) { - this.visibleGroups.forEach((g) => (g.checked = (event.target as HTMLInputElement).checked)); + this.dataSource.filteredData.forEach( + (g) => (g.checked = (event.target as HTMLInputElement).checked), + ); } - isPaging() { - const searching = this.isSearching; - if (searching && this.didScroll) { - this.resetPaging(); - } - return !searching && this.groups && this.groups.length > this.pageSize; - } - - private removeGroup(id: string) { - const index = this.groups.findIndex((g) => g.details.id === id); - if (index > -1) { - this.groups.splice(index, 1); - this.resetPaging(); - this.updateSearchedGroups(); - } + private removeGroup(groupRow: GroupDetailsRow) { + // Assign a new array to dataSource.data to trigger the setters and update the table + this.dataSource.data = this.dataSource.data.filter((g) => g !== groupRow); } private async toCollectionMap(response: ListResponse) { @@ -344,21 +247,9 @@ export class GroupsComponent implements OnInit, OnDestroy { const decryptedCollections = await this.collectionService.decryptMany(collections); // Convert to an object using collection Ids as keys for faster name lookups - const collectionMap: CollectionViewMap = {}; + const collectionMap: Record = {}; decryptedCollections.forEach((c) => (collectionMap[c.id] = c)); return collectionMap; } - - private updateSearchedGroups() { - if (this.isSearching) { - // Making use of the pipe in the component as we need know which groups where filtered - this.searchedGroups = this.searchPipe.transform( - this.groups, - this.searchText, - (group) => group.details.name, - (group) => group.details.id, - ); - } - } } diff --git a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.html b/apps/web/src/app/admin-console/organizations/manage/new-groups.component.html deleted file mode 100644 index 1254d48cc76..00000000000 --- a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - {{ "loading" | i18n }} - - -

    {{ "noGroupsInList" | i18n }}

    - - - - - - - - - - {{ "name" | i18n }} - {{ "collections" | i18n }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    diff --git a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts b/apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts deleted file mode 100644 index e5e99333e64..00000000000 --- a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts +++ /dev/null @@ -1,255 +0,0 @@ -import { Component } from "@angular/core"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { FormControl } from "@angular/forms"; -import { ActivatedRoute } from "@angular/router"; -import { - BehaviorSubject, - combineLatest, - concatMap, - from, - lastValueFrom, - map, - switchMap, - tap, -} from "rxjs"; -import { debounceTime, first } from "rxjs/operators"; - -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; -import { CollectionData } from "@bitwarden/common/vault/models/data/collection.data"; -import { Collection } from "@bitwarden/common/vault/models/domain/collection"; -import { - CollectionDetailsResponse, - CollectionResponse, -} from "@bitwarden/common/vault/models/response/collection.response"; -import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; -import { DialogService, TableDataSource, ToastService } from "@bitwarden/components"; - -import { InternalGroupService as GroupService, GroupView } from "../core"; - -import { - GroupAddEditDialogResultType, - GroupAddEditTabType, - openGroupAddEditDialog, -} from "./group-add-edit.component"; - -type GroupDetailsRow = { - /** - * Details used for displaying group information - */ - details: GroupView; - - /** - * True if the group is selected in the table - */ - checked?: boolean; - - /** - * A list of collection names the group has access to - */ - collectionNames?: string[]; -}; - -/** - * Custom filter predicate that filters the groups table by id and name only. - * This is required because the default implementation searches by all properties, which can unintentionally match - * with members' names (who are assigned to the group) or collection names (which the group has access to). - */ -const groupsFilter = (filter: string) => { - const transformedFilter = filter.trim().toLowerCase(); - return (data: GroupDetailsRow) => { - const group = data.details; - - return ( - group.id.toLowerCase().indexOf(transformedFilter) != -1 || - group.name.toLowerCase().indexOf(transformedFilter) != -1 - ); - }; -}; - -@Component({ - templateUrl: "new-groups.component.html", -}) -export class NewGroupsComponent { - loading = true; - organizationId: string; - - protected dataSource = new TableDataSource(); - protected searchControl = new FormControl(""); - - // Fixed sizes used for cdkVirtualScroll - protected rowHeight = 46; - protected rowHeightClass = `tw-h-[46px]`; - - protected ModalTabType = GroupAddEditTabType; - private refreshGroups$ = new BehaviorSubject(null); - - constructor( - private apiService: ApiService, - private groupService: GroupService, - private route: ActivatedRoute, - private i18nService: I18nService, - private dialogService: DialogService, - private logService: LogService, - private collectionService: CollectionService, - private toastService: ToastService, - ) { - this.route.params - .pipe( - tap((params) => (this.organizationId = params.organizationId)), - switchMap(() => - combineLatest([ - // collectionMap - from(this.apiService.getCollections(this.organizationId)).pipe( - concatMap((response) => this.toCollectionMap(response)), - ), - // groups - this.refreshGroups$.pipe( - switchMap(() => this.groupService.getAll(this.organizationId)), - ), - ]), - ), - map(([collectionMap, groups]) => { - return groups.map((g) => ({ - id: g.id, - name: g.name, - details: g, - checked: false, - collectionNames: g.collections - .map((c) => collectionMap[c.id]?.name) - .sort(this.i18nService.collator?.compare), - })); - }), - takeUntilDestroyed(), - ) - .subscribe((groups) => { - this.dataSource.data = groups; - this.loading = false; - }); - - // Connect the search input to the table dataSource filter input - this.searchControl.valueChanges - .pipe(debounceTime(200), takeUntilDestroyed()) - .subscribe((v) => (this.dataSource.filter = groupsFilter(v))); - - this.route.queryParams.pipe(first(), takeUntilDestroyed()).subscribe((qParams) => { - this.searchControl.setValue(qParams.search); - }); - } - - async edit( - group: GroupDetailsRow, - startingTabIndex: GroupAddEditTabType = GroupAddEditTabType.Info, - ) { - const dialogRef = openGroupAddEditDialog(this.dialogService, { - data: { - initialTab: startingTabIndex, - organizationId: this.organizationId, - groupId: group != null ? group.details.id : null, - }, - }); - - const result = await lastValueFrom(dialogRef.closed); - - if (result == GroupAddEditDialogResultType.Saved) { - this.refreshGroups$.next(); - } else if (result == GroupAddEditDialogResultType.Deleted) { - this.removeGroup(group); - } - } - - async add() { - await this.edit(null); - } - - async delete(groupRow: GroupDetailsRow) { - const confirmed = await this.dialogService.openSimpleDialog({ - title: groupRow.details.name, - content: { key: "deleteGroupConfirmation" }, - type: "warning", - }); - if (!confirmed) { - return false; - } - - try { - await this.groupService.delete(this.organizationId, groupRow.details.id); - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("deletedGroupId", groupRow.details.name), - }); - this.removeGroup(groupRow); - } catch (e) { - this.logService.error(e); - } - } - - async deleteAllSelected() { - const groupsToDelete = this.dataSource.data.filter((g) => g.checked); - - if (groupsToDelete.length == 0) { - return; - } - - const deleteMessage = groupsToDelete.map((g) => g.details.name).join(", "); - const confirmed = await this.dialogService.openSimpleDialog({ - title: { - key: "deleteMultipleGroupsConfirmation", - placeholders: [groupsToDelete.length.toString()], - }, - content: deleteMessage, - type: "warning", - }); - if (!confirmed) { - return false; - } - - try { - await this.groupService.deleteMany( - this.organizationId, - groupsToDelete.map((g) => g.details.id), - ); - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("deletedManyGroups", groupsToDelete.length.toString()), - }); - - groupsToDelete.forEach((g) => this.removeGroup(g)); - } catch (e) { - this.logService.error(e); - } - } - - check(groupRow: GroupDetailsRow) { - groupRow.checked = !groupRow.checked; - } - - toggleAllVisible(event: Event) { - this.dataSource.filteredData.forEach( - (g) => (g.checked = (event.target as HTMLInputElement).checked), - ); - } - - private removeGroup(groupRow: GroupDetailsRow) { - // Assign a new array to dataSource.data to trigger the setters and update the table - this.dataSource.data = this.dataSource.data.filter((g) => g !== groupRow); - } - - private async toCollectionMap(response: ListResponse) { - const collections = response.data.map( - (r) => new Collection(new CollectionData(r as CollectionDetailsResponse)), - ); - const decryptedCollections = await this.collectionService.decryptMany(collections); - - // Convert to an object using collection Ids as keys for faster name lookups - const collectionMap: Record = {}; - decryptedCollections.forEach((c) => (collectionMap[c.id] = c)); - - return collectionMap; - } -} diff --git a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts index 2c8c52efc6a..538cc45ac63 100644 --- a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts @@ -2,7 +2,6 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; import { authGuard } from "@bitwarden/angular/auth/guards"; -import { featureFlaggedRoute } from "@bitwarden/angular/platform/utils/feature-flagged-route"; import { canAccessOrgAdmin, canAccessGroupsTab, @@ -12,16 +11,15 @@ import { canAccessSettingsTab, } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { organizationPermissionsGuard } from "../../admin-console/organizations/guards/org-permissions.guard"; import { organizationRedirectGuard } from "../../admin-console/organizations/guards/org-redirect.guard"; import { OrganizationLayoutComponent } from "../../admin-console/organizations/layouts/organization-layout.component"; -import { GroupsComponent } from "../../admin-console/organizations/manage/groups.component"; -import { NewGroupsComponent } from "../../admin-console/organizations/manage/new-groups.component"; import { deepLinkGuard } from "../../auth/guards/deep-link.guard"; import { VaultModule } from "../../vault/org-vault/vault.module"; +import { GroupsComponent } from "./manage/groups.component"; + const routes: Routes = [ { path: ":organizationId", @@ -49,18 +47,14 @@ const routes: Routes = [ path: "members", loadChildren: () => import("./members").then((m) => m.MembersModule), }, - ...featureFlaggedRoute({ - defaultComponent: GroupsComponent, - flaggedComponent: NewGroupsComponent, - featureFlag: FeatureFlag.GroupsComponentRefactor, - routeOptions: { - path: "groups", - canActivate: [organizationPermissionsGuard(canAccessGroupsTab)], - data: { - titleId: "groups", - }, + { + component: GroupsComponent, + path: "groups", + canActivate: [organizationPermissionsGuard(canAccessGroupsTab)], + data: { + titleId: "groups", }, - }), + }, { path: "reporting", loadChildren: () => diff --git a/apps/web/src/app/admin-console/organizations/organization.module.ts b/apps/web/src/app/admin-console/organizations/organization.module.ts index 79f3a8e5f7d..459948d0f13 100644 --- a/apps/web/src/app/admin-console/organizations/organization.module.ts +++ b/apps/web/src/app/admin-console/organizations/organization.module.ts @@ -6,7 +6,6 @@ import { LooseComponentsModule } from "../../shared"; import { CoreOrganizationModule } from "./core"; import { GroupAddEditComponent } from "./manage/group-add-edit.component"; import { GroupsComponent } from "./manage/groups.component"; -import { NewGroupsComponent } from "./manage/new-groups.component"; import { OrganizationsRoutingModule } from "./organization-routing.module"; import { SharedOrganizationModule } from "./shared"; import { AccessSelectorModule } from "./shared/components/access-selector"; @@ -20,6 +19,6 @@ import { AccessSelectorModule } from "./shared/components/access-selector"; LooseComponentsModule, ScrollingModule, ], - declarations: [GroupsComponent, NewGroupsComponent, GroupAddEditComponent], + declarations: [GroupsComponent, GroupAddEditComponent], }) export class OrganizationModule {} diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 0e70e6db448..ce00640fa9b 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -22,7 +22,6 @@ export enum FeatureFlag { TwoFactorComponentRefactor = "two-factor-component-refactor", EnableTimeThreshold = "PM-5864-dollar-threshold", InlineMenuPositioningImprovements = "inline-menu-positioning-improvements", - GroupsComponentRefactor = "groups-component-refactor", ProviderClientVaultPrivacyBanner = "ac-2833-provider-client-vault-privacy-banner", VaultBulkManagementAction = "vault-bulk-management-action", AC2828_ProviderPortalMembersPage = "AC-2828_provider-portal-members-page", @@ -60,7 +59,6 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.TwoFactorComponentRefactor]: FALSE, [FeatureFlag.EnableTimeThreshold]: FALSE, [FeatureFlag.InlineMenuPositioningImprovements]: FALSE, - [FeatureFlag.GroupsComponentRefactor]: FALSE, [FeatureFlag.ProviderClientVaultPrivacyBanner]: FALSE, [FeatureFlag.VaultBulkManagementAction]: FALSE, [FeatureFlag.AC2828_ProviderPortalMembersPage]: FALSE, From c938c21cf28aeddd1fc6666baf46b287b0c26a2e Mon Sep 17 00:00:00 2001 From: Alex Urbina <42731074+urbinaalex17@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:14:14 -0600 Subject: [PATCH 07/46] BRE-183 Manual version downgrade desktop version (#10279) --- apps/desktop/package.json | 2 +- apps/desktop/src/package-lock.json | 4 ++-- apps/desktop/src/package.json | 2 +- package-lock.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 61d4607cea0..f1639dc51a1 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.7.2", + "version": "2024.7.1", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index d3d99c4cfb3..4ba7c6b6336 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.7.2", + "version": "2024.7.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.7.2", + "version": "2024.7.1", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-napi": "file:../desktop_native", diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index a6bd0d9ef39..1793642dab6 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2024.7.2", + "version": "2024.7.1", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/package-lock.json b/package-lock.json index 49d59ba1986..e3ee06a97f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -235,7 +235,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2024.7.2", + "version": "2024.7.1", "hasInstallScript": true, "license": "GPL-3.0" }, From d215bff574c0f8ca0209e211f19746eb33272103 Mon Sep 17 00:00:00 2001 From: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:56:09 -0600 Subject: [PATCH 08/46] Bumped client version(s) (#10283) --- apps/desktop/package.json | 2 +- apps/desktop/src/package-lock.json | 4 ++-- apps/desktop/src/package.json | 2 +- package-lock.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index f1639dc51a1..61d4607cea0 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.7.1", + "version": "2024.7.2", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index 4ba7c6b6336..d3d99c4cfb3 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.7.1", + "version": "2024.7.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.7.1", + "version": "2024.7.2", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-napi": "file:../desktop_native", diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index 1793642dab6..a6bd0d9ef39 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2024.7.1", + "version": "2024.7.2", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/package-lock.json b/package-lock.json index e3ee06a97f4..49d59ba1986 100644 --- a/package-lock.json +++ b/package-lock.json @@ -235,7 +235,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2024.7.1", + "version": "2024.7.2", "hasInstallScript": true, "license": "GPL-3.0" }, From 518310e0f1f4e511f87bf18f51d9f9d18c942de9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:39:23 +0000 Subject: [PATCH 09/46] Autosync the updated translations (#10282) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 141 ++++++++++-- apps/web/src/locales/ar/messages.json | 141 ++++++++++-- apps/web/src/locales/az/messages.json | 143 ++++++++++-- apps/web/src/locales/be/messages.json | 141 ++++++++++-- apps/web/src/locales/bg/messages.json | 163 +++++++++++--- apps/web/src/locales/bn/messages.json | 141 ++++++++++-- apps/web/src/locales/bs/messages.json | 141 ++++++++++-- apps/web/src/locales/ca/messages.json | 141 ++++++++++-- apps/web/src/locales/cs/messages.json | 151 ++++++++++--- apps/web/src/locales/cy/messages.json | 141 ++++++++++-- apps/web/src/locales/da/messages.json | 153 ++++++++++--- apps/web/src/locales/de/messages.json | 153 ++++++++++--- apps/web/src/locales/el/messages.json | 259 +++++++++++++++------- apps/web/src/locales/en_GB/messages.json | 141 ++++++++++-- apps/web/src/locales/en_IN/messages.json | 141 ++++++++++-- apps/web/src/locales/eo/messages.json | 141 ++++++++++-- apps/web/src/locales/es/messages.json | 141 ++++++++++-- apps/web/src/locales/et/messages.json | 141 ++++++++++-- apps/web/src/locales/eu/messages.json | 141 ++++++++++-- apps/web/src/locales/fa/messages.json | 141 ++++++++++-- apps/web/src/locales/fi/messages.json | 193 ++++++++++++---- apps/web/src/locales/fil/messages.json | 141 ++++++++++-- apps/web/src/locales/fr/messages.json | 141 ++++++++++-- apps/web/src/locales/gl/messages.json | 141 ++++++++++-- apps/web/src/locales/he/messages.json | 141 ++++++++++-- apps/web/src/locales/hi/messages.json | 141 ++++++++++-- apps/web/src/locales/hr/messages.json | 141 ++++++++++-- apps/web/src/locales/hu/messages.json | 151 ++++++++++--- apps/web/src/locales/id/messages.json | 141 ++++++++++-- apps/web/src/locales/it/messages.json | 141 ++++++++++-- apps/web/src/locales/ja/messages.json | 167 +++++++++++--- apps/web/src/locales/ka/messages.json | 141 ++++++++++-- apps/web/src/locales/km/messages.json | 141 ++++++++++-- apps/web/src/locales/kn/messages.json | 141 ++++++++++-- apps/web/src/locales/ko/messages.json | 141 ++++++++++-- apps/web/src/locales/lv/messages.json | 141 ++++++++++-- apps/web/src/locales/ml/messages.json | 141 ++++++++++-- apps/web/src/locales/mr/messages.json | 141 ++++++++++-- apps/web/src/locales/my/messages.json | 141 ++++++++++-- apps/web/src/locales/nb/messages.json | 141 ++++++++++-- apps/web/src/locales/ne/messages.json | 141 ++++++++++-- apps/web/src/locales/nl/messages.json | 153 ++++++++++--- apps/web/src/locales/nn/messages.json | 141 ++++++++++-- apps/web/src/locales/or/messages.json | 141 ++++++++++-- apps/web/src/locales/pl/messages.json | 141 ++++++++++-- apps/web/src/locales/pt_BR/messages.json | 265 +++++++++++++++------- apps/web/src/locales/pt_PT/messages.json | 151 ++++++++++--- apps/web/src/locales/ro/messages.json | 141 ++++++++++-- apps/web/src/locales/ru/messages.json | 153 ++++++++++--- apps/web/src/locales/si/messages.json | 141 ++++++++++-- apps/web/src/locales/sk/messages.json | 141 ++++++++++-- apps/web/src/locales/sl/messages.json | 141 ++++++++++-- apps/web/src/locales/sr/messages.json | 159 +++++++++++--- apps/web/src/locales/sr_CS/messages.json | 141 ++++++++++-- apps/web/src/locales/sv/messages.json | 143 ++++++++++-- apps/web/src/locales/te/messages.json | 141 ++++++++++-- apps/web/src/locales/th/messages.json | 141 ++++++++++-- apps/web/src/locales/tr/messages.json | 177 +++++++++++---- apps/web/src/locales/uk/messages.json | 177 +++++++++++---- apps/web/src/locales/vi/messages.json | 269 ++++++++++++++++------- apps/web/src/locales/zh_CN/messages.json | 173 +++++++++++---- apps/web/src/locales/zh_TW/messages.json | 141 ++++++++++-- 62 files changed, 7777 insertions(+), 1639 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 2505b698b9b..d0b6acf87a3 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Skrap item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Toegangbeheer" }, - "groupAccessAllItems": { - "message": "Hierdie groep het toegang tot alle items en kan dit wysig." - }, - "groupAccessSelectedCollections": { - "message": "Hierdie groep het slegs toegang tot die gekose versamelings." - }, "readOnly": { "message": "Leesalleen" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "Hierdie gebruiker het toegang tot alle items en kan dit wysig." - }, - "userAccessSelectedCollections": { - "message": "Hierdie gebruiker het slegs toegang tot die gekose versamelings." - }, "search": { "message": "Soek" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Uitnodiging is Aanvaar" }, @@ -4377,6 +4386,9 @@ "message": "Send-skakel", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopieer Send-skakel", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "of", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "probeer dit nou", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index c097deca5cf..3fc0312b113 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "حذف العنصر" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "بحث" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "أو", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "جربه الآن", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 79ae71a661b..49dd882cad0 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Elementi sil" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Xaricə köçürülən faylın şifrəsi açılarkən xəta baş verdi. Şifrələmə açarınız, datanı xaricə köçürmək üçün istifadə edilən şifrələmə açarı ilə uyuşmur." }, - "importDestination": { - "message": "Hədəfi daxilə köçür" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Daxilə köçürmə seçimlərinizi öyrənin" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Müraciət nəzarəti" }, - "groupAccessAllItems": { - "message": "Bu qrup, bütün elementlərə müraciət edə və onları dəyişdirə bilər." - }, - "groupAccessSelectedCollections": { - "message": "Bu qrup, yalnız seçilmiş kolleksiyalara müraciət edə bilər." - }, "readOnly": { "message": "Yalnız-oxunan" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Bu istifadəçinin hesabını qorumaq üçün iki addımlı giriş istifadə edilir." }, - "userAccessAllItems": { - "message": "Bu istifadəçi bütün elementlərə müraciət edə və onları dəyişdirə bilər." - }, - "userAccessSelectedCollections": { - "message": "Bu istifadəçi, yalnız seçilmiş kolleksiyalara müraciət edə bilər." - }, "search": { "message": "Axtar" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Yuxarıdakı təşkilata qoşulmaq üçün dəvət edildiniz. Dəvəti qəbul etmək üçün Bitwarden hesabına giriş etməli və ya yeni bir hesab yaratmalısınız." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Dəvət qəbul edildi" }, @@ -4377,6 +4386,9 @@ "message": "\"Send\" bağlantısı", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "\"Send\" bağlantısını kopyala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "və ya", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "indi sınayın", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "Bu kolleksiyalara təyin et" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Yalnız bu kolleksiyalara müraciəti olan təşkilat üzvləri bu elementləri görə biləcək." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { "message": "Təyin ediləcək kolleksiyaları seçin" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Qovluq seç" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ seçilmiş təşkilata birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$, $ORG$ təşkilatına birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "satın alınmış yerlər silindi" } diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index 8ee60ec12a2..afbebdf3495 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Выдаліць элемент" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Памылка дэшыфроўкі экспартаванага файла. Ваш ключ шыфравання не супадае з ключом шыфравання, які выкарыстоўваецца для экспартавання даных." }, - "importDestination": { - "message": "Імпартаванне прызначэння" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Даведацца пра параметры імпартавання" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Кантроль доступу" }, - "groupAccessAllItems": { - "message": "Гэта група можа мець доступ і змяняць усе элементы." - }, - "groupAccessSelectedCollections": { - "message": "Гэта група можа мець доступ толькі да выбраных калекцый." - }, "readOnly": { "message": "Толькі чытанне" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Гэты карыстальнік выкарыстоўвае двухэтапны ўваход для абароны свайго ўліковага запісу." }, - "userAccessAllItems": { - "message": "Гэты карыстальнік можа атрымліваць доступ і змяняць усе элементы." - }, - "userAccessSelectedCollections": { - "message": "Гэты карыстальнік можа мець доступ толькі да выбраных калекцый." - }, "search": { "message": "Пошук" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Вас запрасілі далучыцца да арганізацыі, якая азначана вышэй. Для таго, каб прыняць запрашэнне, вам неабходна ўвайсці або стварыць новы ўліковы запіс Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Запрашэнне прынята" }, @@ -4377,6 +4386,9 @@ "message": "Спасылка на Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Скапіяваць спасылку на Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "або", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "паспрабаваць зараз", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index a04ea2adc74..2e91d7fe638 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -43,10 +43,10 @@ "message": "Име на притежателя на картата" }, "loginCredentials": { - "message": "Login credentials" + "message": "Данни за вписване" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Ключ за удостоверяване" }, "number": { "message": "Номер" @@ -145,13 +145,13 @@ "message": "Удостоверителен ключ (TOTP)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Направете 2-стъпковото удостоверяване безпроблемно и незабележимо" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Битуорден може да съхранява и попълва кодовете за 2-стъпково потвърждаване. Копирайте ключа в това поле." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Битуорден може да съхранява и попълва кодовете за 2-стъпково потвърждаване. Изберете иконката с камера, за да направите екранна снимка на QR-кода от този уеб сайт или копирайте ключа в това поле." }, "folder": { "message": "Папка" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Елементите са преместени в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Елементът е преместен в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Изтриване на елемента" }, @@ -628,16 +646,16 @@ "message": "Сесията ви изтече." }, "restartRegistration": { - "message": "Restart registration" + "message": "Рестартиране на регистрацията" }, "expiredLink": { - "message": "Expired link" + "message": "Връзка с изтекла давност" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Рестартирайте регистрацията или опитайте да се впишете." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Може вече да имате регистрация" }, "logOutConfirmation": { "message": "Сигурни ли сте, че искате да се отпишете?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Грешка при дешифрирането на изнесения файл. Ключът за шифриране не отговаря на този, който е използван за изнасянето на данните." }, - "importDestination": { - "message": "Място на внасяне" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Научете повече относно възможностите за внасяне" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Управление на достъпа" }, - "groupAccessAllItems": { - "message": "Тази група има достъп до всички записи." - }, - "groupAccessSelectedCollections": { - "message": "Тази група има достъп само до избраните колекции." - }, "readOnly": { "message": "Само за четене" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Този потребител използва двустепенна защита за достъп." }, - "userAccessAllItems": { - "message": "Този потребител има достъп до всички записи и може да ги редактира." - }, - "userAccessSelectedCollections": { - "message": "Този потребител има достъп само до избраната колекция." - }, "search": { "message": "Търсене" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Поканени сте да се присъедините към посочената по-горе организация. За да приемете, ще трябва да се впишете в абонамента си към Битуорден. Ако нямате такъв, ще трябва да създадете безплатен абонамент и след това да се впишете в него." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Завършете присъединяването си към тази организация като зададете главна парола." + }, "inviteAccepted": { "message": "Поканата е приета" }, @@ -3811,7 +3820,7 @@ "message": "Не сте избрали нищо." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Получавайте съвети, обявления и предложения за участие в проучвания от Битуорден в пощенската си кутия." }, "unsubscribe": { "message": "Отписване" @@ -4377,6 +4386,9 @@ "message": "Изпращане на връзката", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Копиране на връзката към изпратеното", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "или", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "пробвайте още сега", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "Свързване с тези колекции" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Само членовете на организацията, които имат достъп до тези колекции, ще могат да виждат елемента." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Само членовете на организацията, които имат достъп до тези колекции, ще могат да виждат елементите." }, "selectCollectionsToAssign": { "message": "Изберете колекции за свързване" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Изберете папка" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ ще бъдат преместени завинаги в избраната организация. Вече няма да притежавате тези елементи.", + "personalItemTransferWarningSingular": { + "message": "1 елемент ще бъде преместен завинаги в избраната организация. Вече няма да притежавате този елемент." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ елемента ще бъдат преместени завинаги в избраната организация. Вече няма да притежавате тези елементи.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ ще бъдат преместени завинаги в $ORG$. Вече няма да притежавате тези елементи.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 елемент ще бъде преместен завинаги в $ORG$. Вече няма да притежавате този елемент.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ елемента ще бъдат преместени завинаги в $ORG$. Вече няма да притежавате тези елементи.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Данни" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index 8a0ea4f919b..8ff8067e91e 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "লিঙ্ক পাঠান", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 803c5e1ec0d..349047b549b 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Izbrišite Stavku" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 953e5c8c0da..86660380dba 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Suprimeix element" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error en desxifrar el fitxer exportat. La vostra clau de xifratge no coincideix amb la clau de xifratge utilitzada per exportar les dades." }, - "importDestination": { - "message": "Importa destinació" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Obteniu informació sobre les opcions d'importació" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Control d'accés" }, - "groupAccessAllItems": { - "message": "Aquest grup pot accedir i modificar tots els elements." - }, - "groupAccessSelectedCollections": { - "message": "Aquest grup només pot accedir a les col·leccions seleccionades." - }, "readOnly": { "message": "Només de lectura" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Aquest usuari fa servir l'inici de sessió en dues passes per protegir el seu compte." }, - "userAccessAllItems": { - "message": "Aquest usuari pot accedir i modificar tots els elements." - }, - "userAccessSelectedCollections": { - "message": "Aquest usuari només pot accedir a les col·leccions seleccionades." - }, "search": { "message": "Cerca" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Heu estat convidat a unir-vos a l'organització llistada més amunt. Per acceptar la invitació, heu d'iniciar sessió o crear un compte nou a Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitació acceptada" }, @@ -4377,6 +4386,9 @@ "message": "Enllaç Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copia l'enllaç Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "o", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "prova-ho ara", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assigna a aquestes col·leccions" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index f7b8bb6f28c..1a480ad747d 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Položky přesunuty do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Položka přesunuta do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Smazat položku" }, @@ -628,16 +646,16 @@ "message": "Platnost přihlášení vypršela." }, "restartRegistration": { - "message": "Restart registration" + "message": "Restartovat registraci" }, "expiredLink": { - "message": "Expired link" + "message": "Platnost odkazu vypršela" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Restartujte registraci nebo se zkuste přihlásit." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Už možná máte účet" }, "logOutConfirmation": { "message": "Opravdu se chcete odhlásit?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Chyba při dešifrování exportovaného souboru. Váš šifrovací klíč se neshoduje s klíčem použitým během exportu dat." }, - "importDestination": { - "message": "Cíl importu" + "destination": { + "message": "Cíl" }, "learnAboutImportOptions": { "message": "Více o volbách importu" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Správa přístupů" }, - "groupAccessAllItems": { - "message": "Tato skupina může vidět a upravovat vše." - }, - "groupAccessSelectedCollections": { - "message": "Tato skupina může vidět a upravovat jen vybrané kolekce." - }, "readOnly": { "message": "Jen ke čtení" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Tento uživatel používá pro ochranu svého účtu dvoufázové přihlášení." }, - "userAccessAllItems": { - "message": "Tento uživatel může vidět a upravovat vše." - }, - "userAccessSelectedCollections": { - "message": "Tento uživatel může vidět a upravovat jen vybrané kolekce." - }, "search": { "message": "Hledat" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Byli jste pozváni do výše uvedené organizace. Chcete-li přijmout pozvánku, musíte se přihlásit nebo vytvořit nový účet na Bitwardenu." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Dokončete připojení k této organizaci nastavením hlavního hesla." + }, "inviteAccepted": { "message": "Pozvánka byla přijata" }, @@ -3811,7 +3820,7 @@ "message": "Nevybrali jste žádné položky." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Dostávejte do své e-mailové schránky rady, oznámení a příležitosti k výzkumu od společnosti Bitwarden." }, "unsubscribe": { "message": "Odhlásit odběr" @@ -4377,6 +4386,9 @@ "message": "Odkaz pro Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Kopírovat odkaz" + }, "copySendLink": { "message": "Kopírovat odkaz pro Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "nebo", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Vývojáři i IT týmy si vybírají Správce tajných klíčů Bitwardenu pro bezpečnou správu a nasazení do jejich své infrastruktury a tajných klíčů." + }, + "centralizeSecretsManagement": { + "message": "Centralizujte správu tajných klíčů." + }, + "centralizeSecretsManagementDescription": { + "message": "Bezpečně ukládejte a spravujte tajné klíče na jednom místě, aby se zabránilo rozšíření tajných klíčů napříč Vaší organizací." + }, + "preventSecretLeaks": { + "message": "Zabraňte únikům tajných klíčů." + }, + "preventSecretLeaksDescription": { + "message": "Chraňte tajné klíče pomocí end-to-end šifrování. Už žádné pevné kódování tajných klíčů ani sdílení pomocí souborů .env." + }, + "enhanceDeveloperProductivity": { + "message": "Zvyšte produktivitu vývojářů." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programově získávejte a nasazujte tajné klíče za běhu, aby se vývojáři mohli soustředit na to nejdůležitější, například na zlepšování kvality kódu." + }, + "strengthenBusinessSecurity": { + "message": "Posilte zabezpečení podniku." + }, + "strengthenBusinessSecurityDescription": { + "message": "Udržujte přísnou kontrolu nad přístupem strojů a lidí ke klíčům pomocí integrace SSO, protokolů událostí a rotace přístupu." + }, + "tryItNow": { + "message": "Vyzkoušejte nyní" + }, + "sendRequest": { + "message": "Odeslat požadavek" + }, + "addANote": { + "message": "Přidat poznámku" + }, + "bitwardenSecretsManager": { + "message": "Správce tajných klíčů Bitwardenu" + }, + "moreProductsFromBitwarden": { + "message": "Více produktů od Bitwardenu" + }, + "requestAccessToSecretsManager": { + "message": "Požádat o přístup ke správci tajných klíčů" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "Potřebujete schválení správce, abyste mohli vyzkoušet správce tajných klíčů." + }, + "smAccessRequestEmailSent": { + "message": "Žádost o přístup k e-mailu správce tajných klíčů odeslaná administrátorům." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Zdravím,\n\nžádám o předplatné Správce tajných klíčů Bitwardenu pro náš tým. Vaše podpora by pro nás znamenala mnoho!\n\nSprávce tajných klíčů Bitwardenu je end-to-end řešení pro správu šifrovaných tajných klíčů pro bezpečné ukládání, sdílení a nasazení strojových pověření, jako jsou klíče API, databázová hesla a ověřovací certifikáty.\n\nSprávce klíčů nám pomůže:\n\n- zlepšit zabezpečení\n- zjednodušit provoz\n- zabránit nákladným únikům tajných klíčů\n\nChcete-li požádat o bezplatnou zkušební verzi pro náš tým, obraťte se na společnost Bitwarden.\n\nDěkujeme Vám za pomoc!" + }, + "giveMembersAccess": { + "message": "Umožnit členům přístup:" + }, + "viewAndSelectTheMembers": { + "message": "zobrazit a vybrat členy, které chcete povolit přístup do správce tajných klíčů." + }, + "openYourOrganizations": { + "message": "Otevřít" + }, + "usingTheMenuSelect": { + "message": "V menu vyberte" + }, + "toGrantAccessToSelectedMembers": { + "message": "pro udělení přístupu vybraným členům." + }, "sendVaultCardTryItNow": { "message": "to teď vyzkoušejte", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Přiřadit k těmto kolekcím" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Jen členové organizace s přístupem k těmto kolekcím budou moci vidět položku." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Jen členové organizace s přístupem k těmto kolekcím budou moci vidět položky." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Vybrat složku" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ bude trvale převedeno do vybrané organizace. Tyto položky již nebudete vlastnit.", + "personalItemTransferWarningSingular": { + "message": "1 položka bude trvale převedena do vybrané organizace. Tuto položku již nebudete vlastnit." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ položek bude trvale převedeno do vybrané organizace. Tyto položky již nebudete vlastnit.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ bude trvale převedeno do $ORG$. Tyto položky již nebudete vlastnit.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 položka bude trvale převedena do $ORG$. Tuto položku již nebudete vlastnit.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ položek bude trvale převedeno do $ORG$. Tyto položky již nebudete vlastnit.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "zakoupení uživatelé odebráni" } diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index ddf33bd7225..d7a4db8be40 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index ce90429020b..9f9be80162b 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Emner flyttet til $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Emne flyttet til $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Slet emne" }, @@ -628,16 +646,16 @@ "message": "Login-session udløbet." }, "restartRegistration": { - "message": "Restart registration" + "message": "Genstart registrering" }, "expiredLink": { - "message": "Expired link" + "message": "Udløbet link" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Genstart registreringen eller prøv at logge ind." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Har allerede oprettet en konto?" }, "logOutConfirmation": { "message": "Sikker på, at du vil logge ud?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Fejl under dekryptering af den eksporterede fil. Krypteringsnøglen matcher ikke den til dataeksporten anvendte krypteringsnøgle." }, - "importDestination": { - "message": "Importér destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Læs om importmuligheder" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Adgangskontrol" }, - "groupAccessAllItems": { - "message": "Denne gruppe kan få adgang til og ændre alle elementer." - }, - "groupAccessSelectedCollections": { - "message": "Denne gruppe kan kun få adgang til de valgte samlinger." - }, "readOnly": { "message": "Læsetilladelse" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Denne bruger benytter totrins-login for at beskytte kontoen." }, - "userAccessAllItems": { - "message": "Denne bruger kan få adgang til og ændre alle elementer." - }, - "userAccessSelectedCollections": { - "message": "Denne bruger kan kun få adgang til de valgte samlinger." - }, "search": { "message": "Søg" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Du er blevet inviteret til at blive medlem af organisationen anført ovenfor. For at acceptere invitationen skal du logge ind eller oprette en ny Bitwarden-konto." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Færdiggør tilmeldingen til denne organisation ved at opsætte en hovedadgangskode." + }, "inviteAccepted": { "message": "Invitation accepteret" }, @@ -3811,7 +3820,7 @@ "message": "Du har ikke valgt noget." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Få råd, bekendtgørelser og forskningsmuligheder fra Bitwarden i indbakken." }, "unsubscribe": { "message": "Afmeld" @@ -4377,6 +4386,9 @@ "message": "Send-link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Kopiér link" + }, "copySendLink": { "message": "Kopiér Send-link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "eller", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Udvikling, DevOps og IT-teams vælger Bitwarden Secrets Manager til sikkert at håndtere og implementere deres infrastruktur og maskinhemmeligheder." + }, + "centralizeSecretsManagement": { + "message": "Centralisér hemmelighedshåndtering." + }, + "centralizeSecretsManagementDescription": { + "message": "Opbevar og håndtér hemmeligheder sikkert på ét sted for at forhindre hemmeligsudspredning på tværs af organisationen." + }, + "preventSecretLeaks": { + "message": "Undgå hemmelighedslækager." + }, + "preventSecretLeaksDescription": { + "message": "Beskyt hemmeligheder med ende-til-ende kryptering. Ikke flere fast kodede hemmeligheder eller deling via .env-filer." + }, + "enhanceDeveloperProductivity": { + "message": "Forbedr udviklerproduktiviteten." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatisk hentning og implementering af hemmeligheder ved kørsel, så udviklere kan fokusere på det, der betyder mest, såsom forbedring af kodekvaliteten." + }, + "strengthenBusinessSecurity": { + "message": "Styrk forretningssikkerheden." + }, + "strengthenBusinessSecurityDescription": { + "message": "Bevar tæt kontrol over maskine og menneskelig adgang til hemmeligheder med SSO-integrationer, begivenhedslogger og adgangsrotation." + }, + "tryItNow": { + "message": "Prøv den nu" + }, + "sendRequest": { + "message": "Indsend anmodning" + }, + "addANote": { + "message": "Tilføj et notat" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "Flere produkter fra Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Anmod om adgang til Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "Man skal have godkendelse fra sin administrator for at afprøve Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Adgangsanmodningsmail til Secrets Manager sendt til admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Giv medlemmer adgang:" + }, + "viewAndSelectTheMembers": { + "message": "Vis og vælg de medlemmer, som skal tildeles adgang til Secrets Manager." + }, + "openYourOrganizations": { + "message": "Åbn organisationens" + }, + "usingTheMenuSelect": { + "message": "Fra menuen, vælg" + }, + "toGrantAccessToSelectedMembers": { + "message": "for at tildele adgang til valgte medlemmer." + }, "sendVaultCardTryItNow": { "message": "prøv det nu", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "Tildel til samlinger" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Kun organisationsmedlemmer med adgang til disse samlinger vil kunne se emnet." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Kun organisationsmedlemmer med adgang til disse samlinger vil kunne se emnerne." }, "selectCollectionsToAssign": { "message": "Vælg samlinger at tildele" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Vælg mappe" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ overføres permanent til den valgte organisation. Man vil ikke længere eje disse emner.", + "personalItemTransferWarningSingular": { + "message": "1 emne overføres permanent til den valgte organisation. Man vil ikke længere være ejeren af dette emne." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ emner overføres permanent til den valgte organisation. Man vil ikke længere være ejeren af disse emner.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ overføres permanent til $ORG$. Man vil ikke længere eje disse emner.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 emne overføres permanent til $ORG$. Man vil ikke længere være ejeren af dette emne.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ emner overføres permanent til $ORG$. Man vil ikke længere være ejeren af disse emner.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "købte pladser fjernet" } diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index fbf41456746..b4e812d819c 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Eintrag löschen" }, @@ -628,16 +646,16 @@ "message": "Ihre Anmeldungsitzung ist abgelaufen." }, "restartRegistration": { - "message": "Restart registration" + "message": "Registrierung neu starten" }, "expiredLink": { - "message": "Expired link" + "message": "Abgelaufener Link" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Bitte starte die Registrierung erneut oder versuche dich anzumelden." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Du hast möglicherweise bereits ein Konto" }, "logOutConfirmation": { "message": "Bist du sicher, dass du dich abmelden möchtest?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Fehler beim Entschlüsseln der exportierten Datei. Dein Verschlüsselungsschlüssel stimmt nicht mit dem beim Export verwendeten Verschlüsselungsschlüssel überein." }, - "importDestination": { - "message": "Import-Ziel" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Erfahre mehr über deine Importoptionen" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Zugriffskontrolle" }, - "groupAccessAllItems": { - "message": "Diese Gruppe kann auf alle Einträge zugreifen und diese ändern." - }, - "groupAccessSelectedCollections": { - "message": "Diese Gruppe kann nur auf die ausgewählten Sammlungen zugreifen." - }, "readOnly": { "message": "Schreibgeschützt" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Dieser Benutzer hat sein Konto mit einer Zwei-Faktor-Authentifizierung geschützt." }, - "userAccessAllItems": { - "message": "Der Benutzer kann alle Einträge einsehen und verändern." - }, - "userAccessSelectedCollections": { - "message": "Der Benutzer kann nur auf ausgewählte Sammlungen zugreifen." - }, "search": { "message": "Suche" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Du wurdest eingeladen, dem oben genannten Organisation beizutreten. Um die Einladung anzunehmen, musst du ein Bitwarden-Konto erstellen oder dich mit deinem bestehenden Bitwarden-Konto anmelden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Einladung angenommen" }, @@ -3811,7 +3820,7 @@ "message": "Sie haben keine Auswahl getroffen." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Erhalte Ratschläge, Ankündigungen und Marktforschungsumfragen von Bitwarden in deinem Posteingang." }, "unsubscribe": { "message": "Deabonnieren" @@ -4377,6 +4386,9 @@ "message": "Send-Link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send-Link kopieren", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "oder", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "probiere es jetzt aus", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "Diesen Sammlungen zuweisen" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Nur Organisationsmitglieder mit Zugriff auf diese Sammlungen können die Einträge sehen." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { "message": "Zu zuweisende Sammlungen auswählen" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Ordner auswählen" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an die ausgewählte Organisation übertragen. Du wirst diese Einträge nicht mehr besitzen.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an $ORG$ übertragen. Du wirst diese Einträge nicht mehr besitzen.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "erworbene Benutzerplätze entfernt" } diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index 2d0a21d05e0..426a14208be 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -43,7 +43,7 @@ "message": "Όνομα κατόχου της κάρτας" }, "loginCredentials": { - "message": "Login credentials" + "message": "Στοιχεία σύνδεσης" }, "authenticatorKey": { "message": "Authenticator key" @@ -189,7 +189,7 @@ "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { - "message": "You", + "message": "Εσείς", "description": "Used as a label to indicate that the user is the owner of an item." }, "addFolder": { @@ -421,13 +421,13 @@ "message": "Στοιχείο" }, "itemDetails": { - "message": "Item details" + "message": "Λεπτομέρειες αντικειμένου" }, "itemName": { - "message": "Item name" + "message": "Όνομα αντικειμένου" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "Δεν μπορείτε να αφαιρέσετε συλλογές που έχουν μόνο δικαιώματα Προβολής: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Διαγραφή στοιχείου" }, @@ -613,31 +631,31 @@ "message": "Πρόσβαση" }, "accessLevel": { - "message": "Access level" + "message": "Επίπεδο πρόσβασης" }, "accessing": { - "message": "Accessing" + "message": "Πρόσβαση" }, "loggedOut": { "message": "Αποσυνδεθήκατε" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Έχετε αποσυνδεθεί από τον λογαριασμό σας." }, "loginExpired": { "message": "Η περίοδος σύνδεσής σας έχει λήξει." }, "restartRegistration": { - "message": "Restart registration" + "message": "Επανεκκίνηση εγγραφής" }, "expiredLink": { - "message": "Expired link" + "message": "Ο σύνδεσμος έληξε" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Παρακαλούμε επανακκινήστε την εγγραφή ή δοκιμάστε να συνδεθείτε." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Μπορεί να έχετε ήδη λογαριασμό" }, "logOutConfirmation": { "message": "Είστε βέβαιοι ότι θέλετε να αποσυνδεθείτε;" @@ -673,10 +691,10 @@ "message": "Keep this window open and follow prompts from your browser." }, "useADifferentLogInMethod": { - "message": "Use a different log in method" + "message": "Χρήση διαφορετικής μεθόδου σύνδεσης" }, "loginWithPasskey": { - "message": "Log in with passkey" + "message": "Σύνδεση με κλειδί πρόσβασης" }, "invalidPasskeyPleaseTryAgain": { "message": "Invalid Passkey. Please try again." @@ -688,31 +706,31 @@ "message": "Use a generated passkey that will automatically log you in without a password. Biometrics, like facial recognition or fingerprint, or another FIDO2 security method will verify your identity." }, "newPasskey": { - "message": "New passkey" + "message": "Νέο κλειδί πρόσβασης" }, "learnMoreAboutPasswordless": { "message": "Learn more about passwordless" }, "creatingPasskeyLoading": { - "message": "Creating passkey..." + "message": "Δημιουργία κλειδιού πρόσβασης..." }, "creatingPasskeyLoadingInfo": { "message": "Keep this window open and follow prompts from your browser." }, "errorCreatingPasskey": { - "message": "Error creating passkey" + "message": "Σφάλμα δημιουργίας κλειδιού πρόσβασης" }, "errorCreatingPasskeyInfo": { "message": "There was a problem creating your passkey." }, "passkeySuccessfullyCreated": { - "message": "Passkey successfully created!" + "message": "Επιτυχής δημιουργία κλειδιού πρόσβασης!" }, "customPasskeyNameInfo": { "message": "Name your passkey to help you identify it." }, "useForVaultEncryption": { - "message": "Use for vault encryption" + "message": "Χρήση για κρυπτογράφηση θησαυ/κίου" }, "useForVaultEncryptionInfo": { "message": "Log in and unlock on supported devices without your master password. Follow the prompts from your browser to finalize setup." @@ -721,16 +739,16 @@ "message": "Error reading passkey. Try again or uncheck this option." }, "encryptionNotSupported": { - "message": "Encryption not supported" + "message": "Η κρυπτογράφηση δεν υποστηρίζεται" }, "enablePasskeyEncryption": { - "message": "Set up encryption" + "message": "Ορισμός κρυπτογράφησης" }, "usedForEncryption": { - "message": "Used for encryption" + "message": "Χρησιμοποιείται για κρυπτογράφηση" }, "loginWithPasskeyEnabled": { - "message": "Log in with passkey turned on" + "message": "Η σύνδεση με το κλειδί πρόσβασης ενεργοποιήθηκε" }, "passkeySaved": { "message": "$NAME$ saved", @@ -742,10 +760,10 @@ } }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Το κλειδί πρόσβασης αφαιρέθηκε" }, "removePasskey": { - "message": "Remove passkey" + "message": "Αφαίρεση κλειδιού πρόσβασης" }, "removePasskeyInfo": { "message": "If all passkeys are removed, you will be unable to log into new devices without your master password." @@ -754,16 +772,16 @@ "message": "Passkey limit reached. Remove a passkey to add another." }, "tryAgain": { - "message": "Try again" + "message": "Προσπαθήστε ξανά" }, "createAccount": { "message": "Δημιουργία Λογαριασμού" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Ορίστε έναν ισχυρό κωδικό πρόσβασης" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Ολοκληρώστε τη δημιουργία του λογαριασμού σας ορίζοντας έναν κωδικό πρόσβασης" }, "newAroundHere": { "message": "Νέος/α στα μέρη μας;" @@ -775,7 +793,7 @@ "message": "Είσοδος" }, "verifyIdentity": { - "message": "Verify your Identity" + "message": "Επαληθεύστε την ταυτότητά σας" }, "logInInitiated": { "message": "Η σύνδεση ξεκίνησε" @@ -1438,7 +1456,7 @@ "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsLink": { - "message": "new item", + "message": "νέο αντικείμενο", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsPartTwoNoOrgs": { @@ -1468,7 +1486,7 @@ } }, "dataExportSuccess": { - "message": "Data successfully exported" + "message": "Τα δεδομένα εξήχθησαν επιτυχώς" }, "importWarning": { "message": "Εισάγετε δεδομένα στο $ORGANIZATION$. Τα δεδομένα σας μπορεί να μοιραστούν με μέλη αυτού του οργανισμού. Θέλετε να προχωρήσετε;", @@ -1488,17 +1506,17 @@ "importEncKeyError": { "message": "Σφάλμα αποκρυπτογράφησης του εξαγόμενου αρχείου. Το κλειδί κρυπτογράφησης δεν ταιριάζει με το κλειδί κρυπτογράφησης που χρησιμοποιήθηκε για την εξαγωγή των δεδομένων." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "Μάθετε για τις επιλογές εισαγωγής σας" }, "selectImportFolder": { - "message": "Select a folder" + "message": "Επιλέξτε ένα φάκελο" }, "selectImportCollection": { - "message": "Select a collection" + "message": "Επιλέξτε μια συλλογή" }, "importTargetHint": { "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", @@ -1646,7 +1664,7 @@ "message": "Ενεργοποιημένο" }, "restoreAccess": { - "message": "Restore access" + "message": "Επαναφορά πρόσβασης" }, "premium": { "message": "Premium", @@ -1671,13 +1689,13 @@ "message": "Διαχείριση" }, "canManage": { - "message": "Can manage" + "message": "Δυνατότητα διαχείρισης" }, "disable": { "message": "Απενεργοποίηση" }, "revokeAccess": { - "message": "Revoke access" + "message": "Ανάκληση πρόσβασης" }, "twoStepLoginProviderEnabled": { "message": "Ο πάροχος σύνδεσης δύο βημάτων του λογαριασμού σας, είναι ενεργοποιημένος." @@ -1692,13 +1710,13 @@ "message": "," }, "twoStepAuthenticatorInstructionInfix2": { - "message": "or" + "message": "ή" }, "twoStepAuthenticatorInstructionSuffix": { "message": "." }, "continueToExternalUrlTitle": { - "message": "Continue to $URL$?", + "message": "Συνέχεια στο $URL$;", "placeholders": { "url": { "content": "$1", @@ -1725,7 +1743,7 @@ "message": "Κλειδί" }, "twoStepAuthenticatorEnterCodeV2": { - "message": "Verification code" + "message": "Κωδικός επαλήθευσης" }, "twoStepAuthenticatorReaddDesc": { "message": "Σε περίπτωση που χρειαστεί να την προσθέσετε σε άλλη συσκευή, παρακάτω είναι ο κωδικός QR (ή το κλειδί) που απαιτείται από την εφαρμογή επαλήθευσης." @@ -1809,7 +1827,7 @@ "message": "Client Id" }, "twoFactorDuoClientSecret": { - "message": "Client Secret" + "message": "Μυστικό Πελάτη" }, "twoFactorDuoApiHostname": { "message": "API Hostname" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Έλεγχος Πρόσβασης" }, - "groupAccessAllItems": { - "message": "Αυτή η ομάδα μπορεί να έχει πρόσβαση και να τροποποιεί όλα τα στοιχεία." - }, - "groupAccessSelectedCollections": { - "message": "Αυτή η ομάδα μπορεί να έχει πρόσβαση μόνο στις επιλεγμένες συλλογές." - }, "readOnly": { "message": "Μόνο για ανάγνωση" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Αυτός ο χρήστης χρησιμοποιεί τρόπο σύνδεσης δύο βημάτων για να προστατεύσει το λογαριασμό του." }, - "userAccessAllItems": { - "message": "Αυτός ο χρήστης μπορεί να έχει πρόσβαση και να τροποποιεί όλα τα στοιχεία." - }, - "userAccessSelectedCollections": { - "message": "Αυτός ο χρήστης μπορεί να έχει πρόσβαση μόνο στις επιλεγμένες συλλογές." - }, "search": { "message": "Αναζήτηση" }, @@ -2947,7 +2953,7 @@ "message": "Incorrect code" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "Εσφαλμένο PIN" }, "exportedVault": { "message": "Εξαγωγή Vault." @@ -3115,7 +3121,7 @@ } }, "deletedCollections": { - "message": "Deleted collections" + "message": "Διαγραμμένες συλλογές" }, "deletedCollectionId": { "message": "Διεγραμμένη συλλογή $ID$.", @@ -3328,25 +3334,25 @@ "message": "Συσκευή" }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Δημιουργία λογαριασμού στο" }, "checkYourEmail": { - "message": "Check your email" + "message": "Ελέγξτε το ηλ. ταχυδρομείο σας" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Ακολουθήστε το σύνδεσμο στο μήνυμα ηλ. ταχυδρομείου που στάλθηκε στο" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "και συνεχίστε στη δημιουργία του λογαριασμού σας." }, "noEmail": { - "message": "No email?" + "message": "Κανένα μήνυμα ηλ. ταχυδρομείου;" }, "goBack": { - "message": "Go back" + "message": "Επιστροφή" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "για να επεξεργαστείτε τη διεύθυνση ηλ. ταχυδρομείου σας." }, "view": { "message": "Προβολή" @@ -3430,7 +3436,7 @@ "message": "Το email σας έχει επαληθευτεί." }, "emailVerifiedV2": { - "message": "Email verified" + "message": "Η διεύθυνση ηλ. ταχυδρομείου επιβεβαιώθηκε" }, "emailVerifiedFailed": { "message": "Δεν είναι δυνατή η επαλήθευση του email σας. Δοκιμάστε να στείλετε νέο email επαλήθευσης." @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Έχετε προσκληθεί να συμμετάσχετε στον παραπάνω οργανισμό. Για να αποδεχτείτε την πρόσκληση, πρέπει να συνδεθείτε ή να δημιουργήσετε ένα νέο λογαριασμό Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Η Πρόσκληση έγινε αποδεκτή" }, @@ -3499,13 +3508,13 @@ "message": "Ζητήσατε να διαγράψετε το λογαριασμό Bitwarden. Κάντε κλικ στο παρακάτω κουμπί για επιβεβαίωση." }, "deleteRecoverOrgConfirmDesc": { - "message": "You have requested to delete your Bitwarden organization." + "message": "Έχετε ζητήσει να διαγράψετε τον οργανισμό Bitwarden σας." }, "myOrganization": { "message": "Ο οργανισμός μου" }, "organizationInfo": { - "message": "Organization info" + "message": "Πληροφορίες οργανισμού" }, "deleteOrganization": { "message": "Διαγραφή Οργανισμού" @@ -3679,7 +3688,7 @@ "message": "Οι προσαρμογές της συνδρομής σας θα έχουν ως αποτέλεσμα αλλαγές στα σύνολα τιμολόγησης. Εάν οι νεοπροσκεκλημένοι χρήστες υπερβούν τις συνδρομητικές σας θέσεις, θα λάβετε αμέσως μια αναθεωρημένη χρέωση για τους πρόσθετους χρήστες." }, "smStandaloneTrialSeatCountUpdateMessageFragment1": { - "message": "If you want to add additional" + "message": "Αν θέλετε να προσθέσετε επιπλέον" }, "smStandaloneTrialSeatCountUpdateMessageFragment2": { "message": "seats without the bundled offer, please contact" @@ -3814,16 +3823,16 @@ "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Ακύρωση συνδρομής" }, "atAnyTime": { - "message": "at any time." + "message": "οποιαδήποτε στιγμή." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Συνεχίζοντας, συμφωνείτε με" }, "and": { - "message": "and" + "message": "και" }, "acceptPolicies": { "message": "Επιλέγοντας αυτό το πλαίσιο, συμφωνείτε με τα εξής:" @@ -3847,7 +3856,7 @@ "message": "Επιλέξτε πότε θα λήξει το vault και πραγματοποιήστε την επιλεγμένη ενέργεια." }, "vaultTimeoutLogoutDesc": { - "message": "Choose when your vault will be logged out." + "message": "Επιλέξτε πότε το θησαυ/κιό σας θα αποσυνδεθεί." }, "oneMinute": { "message": "1 λεπτό" @@ -4377,6 +4386,9 @@ "message": "Αποστολή Συνδέσμου", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Αντιγραφή Συνδέσμου Αποστολής", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "ή", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "δοκιμάστε το τώρα", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 5a36ac27915..9c4a198b210 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organisation listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organisation by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralise secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organisation." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organisation's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organisation members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organisation members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organisation. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organisation. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organisation. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index 6128c93fb36..558d5e1a2d0 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organisation listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organisation by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send Link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send Link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralise secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organisation." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organisation's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organisation members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organisation members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organisation. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organisation. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organisation. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 9d509e09cc6..3f23fe9c3e2 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Forigi Artikolon" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Eraro de ĉifrado de la elporta dosiero. Via ŝlosilo de ĉifrado ne kongruas kun la ŝlosilo de ĉifrado uzita por elporti la datumojn." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Alirkontrolo" }, - "groupAccessAllItems": { - "message": "Ĉi tiu grupo povas aliri kaj modifi ĉiujn erojn." - }, - "groupAccessSelectedCollections": { - "message": "Ĉi tiu grupo povas aliri nur la elektitajn kolektojn." - }, "readOnly": { "message": "Nurlegebla" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Ĉi tiu uzanto uzas du-paŝan ensaluton por protekti sian konton." }, - "userAccessAllItems": { - "message": "Ĉi tiu uzanto povas aliri kaj modifi ĉiujn erojn." - }, - "userAccessSelectedCollections": { - "message": "Ĉi tiu uzanto povas aliri nur la elektitajn kolektojn." - }, "search": { "message": "Serĉi" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Vi estis invitita aliĝi al la organizo supre listigita. Por akcepti la inviton, vi devas ensaluti aŭ krei novan Bitwarden-konton." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invito Akceptita" }, @@ -4377,6 +4386,9 @@ "message": "Sendi ligon", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopii Sendu Ligilon", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "aŭ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "provu ĝin nun", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 195d184eac3..9233f186056 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Eliminar elemento" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error al descifrar el archivo exportado. Su clave de cifrado no coincide con la clave de cifrado utilizada para exporta los datos." }, - "importDestination": { - "message": "Importar destino" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Conozca sus opciones de importación" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Control de Acceso" }, - "groupAccessAllItems": { - "message": "Este grupo puede acceder y modificar todos los elementos." - }, - "groupAccessSelectedCollections": { - "message": "Este grupo sólo puede acceder a las colecciones seleccionadas." - }, "readOnly": { "message": "Sólo lectura" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Este usuario está usando autenticación de dos pasos para proteger su cuenta." }, - "userAccessAllItems": { - "message": "Este usuario puede acceder y modificar todos los elementos." - }, - "userAccessSelectedCollections": { - "message": "Este usuario sólo puede acceder a las colecciones seleccionadas." - }, "search": { "message": "Buscar" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Usted ha sido invitado a unirse a la organización mencionada anteriormente. Para aceptar la invitación, debe iniciar sesión o crear una nueva cuenta de Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitación Aceptada" }, @@ -4377,6 +4386,9 @@ "message": "Enlace Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copiar enlace Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "o", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "pruébalo ahora", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Asignar a estas colecciones" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index 5a336649014..1e8acff2f72 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Kustuta kirje" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Eksporditud faili dekrüpteerimine nurjus. Sinu krüpteerimisvõti ei ühti selle võtmega, mida kasutati andmete eksportimisel." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Ligipääsu haldamine" }, - "groupAccessAllItems": { - "message": "See grupp pääseb ligi ja saab muuta kõiki kirjeid." - }, - "groupAccessSelectedCollections": { - "message": "See grupp pääseb ligi ainult valitud kirjetele." - }, "readOnly": { "message": "Saab ainult lugeda" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Sellel kasutajal on kaheastmeline kinnitamine sisse lülitatud." }, - "userAccessAllItems": { - "message": "See kasutaja pääseb ligi ja saab muuta kõiki kirjeid." - }, - "userAccessSelectedCollections": { - "message": "See kasutaja pääseb ligi ja saab muuta ainult valitud kollektsioone." - }, "search": { "message": "Otsi" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Sind on kutsutud ülal oleva organisatsiooniga liituma. Liitumise kinnitamiseks pead oma Bitwardeni kontosse sisse logima. Kui sul ei ole veel kontot, saad selle luua." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Kutse on vastu võetud" }, @@ -4377,6 +4386,9 @@ "message": "Sendi link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopeeri Sendi link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "või", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "proovi ise järele", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index 5a6e143fd78..c8abba383c4 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Ezabatu elementua" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Errorea esportatutako fitxategia deszifratzean. Zifratze-gakoa ez dator bat datuak esportatzeko erabilitako zifratze-gakoarekin." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Sarbide kontrola" }, - "groupAccessAllItems": { - "message": "Talde hau elementu guztietara sartu eta aldaketak egin ditzake." - }, - "groupAccessSelectedCollections": { - "message": "Talde hau hautatutako bildumetara soilik sar daiteke." - }, "readOnly": { "message": "Irakurtzeko soilik" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Erabiltzaile hau bi urratseko saio hasiera erabiltzen ari da bere kontua babesteko." }, - "userAccessAllItems": { - "message": "Erabiltzaile hau elementu guztietara sartu eta aldaketak egin ditzake." - }, - "userAccessSelectedCollections": { - "message": "Erabiltzaile hau hautatutako bildumetara soilik sar daiteke." - }, "search": { "message": "Bilatu" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Lehen aipatutako erakundean parte hartzera gonbidatu zaituzte. Gonbidapena onartzeko, saioa hasi edo Bitwarden kontu berri bat sortu behar duzu." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Gonbidapena onartua" }, @@ -4377,6 +4386,9 @@ "message": "Send esteka", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send esteka kopiatu", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "edo", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "saiatu orain", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index d2466d511bc..d6c6ddf1dca 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "حذف مورد" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "خطا در رمزگشایی پرونده‌ی درون ریزی شده. کلید رمزگذاری شما با کلید رمزگذاری استفاده شده برای درون ریزی داده‌ها مطابقت ندارد." }, - "importDestination": { - "message": "مقصد برون ریزی" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "درباره گزینه‌های برون ریزی خود بیاموزید" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "کنترل دسترسی" }, - "groupAccessAllItems": { - "message": "این گروه می‌تواند به همه موارد دسترسی داشته باشد و آن‌ها را تغییر دهد." - }, - "groupAccessSelectedCollections": { - "message": "این گروه فقط می‌تواند به مجموعه های انتخاب شده دسترسی داشته باشد." - }, "readOnly": { "message": "فقط خواندنی" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "این کاربر از ورود دو مرحله ای برای محافظت از حساب خود استفاده می‌کند." }, - "userAccessAllItems": { - "message": "این کاربر می‌تواند به همه موارد دسترسی داشته باشد و آن‌ها را تغییر دهد." - }, - "userAccessSelectedCollections": { - "message": "این کاربر فقط می‌تواند به مجموعه های انتخاب شده دسترسی داشته باشد." - }, "search": { "message": "جستجو" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "شما برای پیوستن به سازمان فهرست شده در بالا دعوت شده اید. برای پذیرش دعوت، باید وارد شوید یا یک حساب کاربری جدید در Bitwarden ایجاد کنید." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "دعوتنامه پذیرفته شد" }, @@ -4377,6 +4386,9 @@ "message": "ارسال پیوند", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "پیوند ارسال را کپی کن", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "یا", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "الان امتحان کنید", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index f70a820c6a4..d51a55e27a7 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -43,10 +43,10 @@ "message": "Kortinhaltijan nimi" }, "loginCredentials": { - "message": "Login credentials" + "message": "Kirjautumistiedot" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Todennusavain" }, "number": { "message": "Numero" @@ -145,13 +145,13 @@ "message": "Todennusavain (TOTP)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Tee kaksivaiheisesta kirjautumisesta saumatonta" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden voi säilyttää ja täyttää kaksivaiheisen kirjautumisen koodit. Kopioi ja liitä todennusavain tähän kenttään." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden voi säilyttää ja täyttää kaksivaiheisen kirjautumisen koodit. Kamerakuvakkeella voit kaapata todennusavaimen avoimen sivun QR-koodista automaattisesti, tai voit kopioida ja liittää sen tähän kenttään manuaalisesti." }, "folder": { "message": "Kansio" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Kohteet siirrettiin organisaatioon $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Kohde siirrettiin organisaatioon $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Poista kohde" }, @@ -628,16 +646,16 @@ "message": "Kirjautumisistuntosi on erääntynyt." }, "restartRegistration": { - "message": "Restart registration" + "message": "Aloita rekisteröityminen alusta" }, "expiredLink": { - "message": "Expired link" + "message": "Vanhentunut linkki" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Aloita rekisteröityminen alusta tai yritä kirjautua sisään uudelleen." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Sinulla saattaa olla jo tili" }, "logOutConfirmation": { "message": "Haluatko varmasti kirjautua ulos?" @@ -673,7 +691,7 @@ "message": "Pidä tämä ikkuna avoinna ja seuraa selaimesi opasteita." }, "useADifferentLogInMethod": { - "message": "Käytä eri kirjautumistapaa" + "message": "Käytä vaihtoehtoista kirjautumistapaa" }, "loginWithPasskey": { "message": "Kirjaudu suojausavaimella" @@ -979,7 +997,7 @@ "message": "Lähetä todennuskoodi sähköpostitse uudelleen" }, "useAnotherTwoStepMethod": { - "message": "Käytä eri todennusmenetelmää" + "message": "Käytä vaihtoehtoista todennustapaa" }, "insertYubiKey": { "message": "Kytke YubiKey-todennuslaitteesi tietokoneen USB-porttiin ja paina sen painiketta." @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Virhe purettaessa viedyn tiedoston salausta. Salausavaimesi ei vastaa viennissä käytettyä salausavainta." }, - "importDestination": { - "message": "Tuontikohde" + "destination": { + "message": "Kohde" }, "learnAboutImportOptions": { "message": "Lue lisää tuontivaihtoehdoista" @@ -1713,10 +1731,10 @@ "message": "Avataanko bitwarden.com?" }, "twoStepContinueToBitwardenUrlDesc": { - "message": "Bitwarden Authenticatorin avulla voit säilyttää todennusavaimet ja luoda TOTP-koodeja kaksivaiheista tunnistautumista varten. Lue lisää bitwarden.com-sivustolta." + "message": "Bitwarden Authenticatorin avulla voit säilyttää todennusavaimet ja luoda TOTP-koodeja kaksivaiheista kirjautumista varten. Lue lisää bitwarden.com-sivustolta." }, "twoStepAuthenticatorScanCodeV2": { - "message": "Skannaa alla oleva QR-koodi todennussovelluksellasi tai syötä avain." + "message": "Skannaa alla oleva QR-koodi todennussovelluksellasi tai syötä avain itse." }, "twoStepAuthenticatorQRCanvasError": { "message": "QR-koodin lataus ei onnistunut. Yritä uudelleen tai käytä alla olevaa avainta." @@ -1899,7 +1917,7 @@ "message": "Suojaamattomat sivustot" }, "unsecuredWebsitesReportDesc": { - "message": "URL-osoitteet, jotka alkavat http://, eivät hyödynnä parasta mahdollista salausta. Vaihda tällaiset kirjatumisosoitteet https://-muotoisiksi turvallisempaa selausta varten." + "message": "URL-osoitteet, jotka alkavat http://, eivät hyödynnä parasta mahdollista salausta. Vaihda tällaiset kirjautumisosoitteet https://-muotoisiksi turvallisempaa selausta varten." }, "unsecuredWebsitesFound": { "message": "Suojaamattomia verkkosivustoja löytyi" @@ -1930,7 +1948,7 @@ "message": "Löytyi kirjautumistietoja, joille ei ole määritetty kaksivaiheista kirjautumista" }, "inactive2faFoundReportDesc": { - "message": "Löysimme holv(e)istasi $COUNT$ sivustoa, joita ei ehkä ole määritetty käyttämään kaksivaiheista tunnistautumista (2fa.directory-sivuston mukaan). Nämä tilit tulisi suojata paremmin määrittämällä niille kaksivaiheinen tunnistautuminen.", + "message": "Löysimme holv(e)istasi $COUNT$ sivustoa, joita ei ehkä ole määritetty käyttämään kaksivaiheista kirjautumista (2fa.directory-sivuston mukaan). Nämä tilit tulisi suojata paremmin määrittämällä niille kaksivaiheinen tunnistautuminen.", "placeholders": { "count": { "content": "$1", @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Käyttöoikeuksien laajuus" }, - "groupAccessAllItems": { - "message": "Tällä ryhmällä on käyttö- ja muokkausoikeudet kaikkiin kohteisiin." - }, - "groupAccessSelectedCollections": { - "message": "Ryhmällä on käyttöoikeudet vain valittuihin kokoelmiin." - }, "readOnly": { "message": "Vain luku" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Käyttäjä on suojannut tilinsä kaksivaiheisella kirjautumisella." }, - "userAccessAllItems": { - "message": "Käyttäjällä on käyttö- ja muokkausoikeus kaikkiin kohteisiin." - }, - "userAccessSelectedCollections": { - "message": "Käyttäjällä on käyttöoikeudet vain valittuihin kokoelmiin." - }, "search": { "message": "Etsi" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Sinut on kutsuttu liittymään yllä mainittuun organisaatioon. Hyväksyäksesi kutsun, sinun tulee kirjautua tilillesi tai luoda uusi Bitwarden-tili." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Viimeistele organisaatioon liittyminen asettamalla pääsalasana." + }, "inviteAccepted": { "message": "Kutsu hyväksyttiin" }, @@ -3811,7 +3820,7 @@ "message": "Et ole valinnut mitään." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Vastaanota Bitwardenilta postilaatikkoosi vinkkejä, uutisia ja tutkimusmahdollisuuksia." }, "unsubscribe": { "message": "Lopeta tilaus" @@ -3985,7 +3994,7 @@ "message": "API-avain" }, "apiKeyDesc": { - "message": "API-avainta voidaan käyttää tunnistautumiseen Bitwardenin julkisen rajapinnan välityksellä (CLI)." + "message": "API-avainta voidaan käyttää tunnistautumiseen Bitwardenin julkista rajapintaa vasten." }, "apiKeyRotateDesc": { "message": "API-avaimen uudistus mitätöi edellisen avaimen. Voit uudistaa API-avaimen, jos uskot, ettei nykyisen avaimen käyttö ole enää turvallista." @@ -4174,7 +4183,7 @@ } }, "vaultTimeoutLogOutConfirmation": { - "message": "Uloskirjautuminen estää pääsyn holviisi ja vaatii ajan umpeuduttua todennuksen Internet-yhteyden välityksellä. Haluatko varmasti käyttää tätä asetusta?" + "message": "Uloskirjautuminen estää pääsyn holviisi ja vaatii ajan umpeuduttua tunnistautumisen Internet-yhteyden välityksellä. Haluatko varmasti käyttää asetusta?" }, "vaultTimeoutLogOutConfirmationTitle": { "message": "Aikakatkaisutoiminnon vahvistus" @@ -4377,6 +4386,9 @@ "message": "Send-linkki", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopioi Send-linkki", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "tai", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Keskitä salaisuuksien hallinta." + }, + "centralizeSecretsManagementDescription": { + "message": "Säilytä ja hallitse salaisuuksia turvallisesti yhdessä paikassa ja estä salaisuuksien leviäminen organisaatiossasi." + }, + "preventSecretLeaks": { + "message": "Estä salaisuuksien vuodot." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Paranna kehittäjien tuottavuutta." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Paranna yrityksen turvallisuutta." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Kokeile sitä nyt" + }, + "sendRequest": { + "message": "Lähetä pyyntö" + }, + "addANote": { + "message": "Lisää muistiinpano" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Salaisuushallinta" + }, + "moreProductsFromBitwarden": { + "message": "Lisää tuotteita Bitwardenilta" + }, + "requestAccessToSecretsManager": { + "message": "Pyydä Salaisuushallinnan käyttöoikeutta" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "Tarvitset ylläpitäjän hyväksynnän kokeillaksesi Salaisuushallintaa." + }, + "smAccessRequestEmailSent": { + "message": "Pääsypyyntö Salaisuushallintaan lähetettiin sähköpostitse ylläpitäjille." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Anna jäsenille pääsy:" + }, + "viewAndSelectTheMembers": { + "message": "tarkastele ja valitse jäseniä, joille haluat antaa pääsyn Salaisuushallintaan." + }, + "openYourOrganizations": { + "message": "Avaa organisaatiosi" + }, + "usingTheMenuSelect": { + "message": "Valitse valikkoa käyttäen" + }, + "toGrantAccessToSelectedMembers": { + "message": "myöntääksesi pääsyn valituille jäsenille." + }, "sendVaultCardTryItNow": { "message": "kokeile sitä nyt", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -5547,7 +5628,7 @@ "message": "Todennuskoodi vaaditaan." }, "webauthnCancelOrTimeout": { - "message": "Todennus peruutettiin tai siinä kesti liian kauan. Yritä uudelleen." + "message": "Tunnistautuminen peruttiin tai se kesti liian kauan. Yritä uudelleen." }, "invalidVerificationCode": { "message": "Virheellinen todennuskoodi" @@ -6241,7 +6322,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Virhe yhdistettäessä Duo-palveluun. Käytä toista kaksivaiheista kirjautumismenetelmää tai ota yhteyttä Duoon saadaksesi apua." + "message": "Virhe yhdistettäessä Duo-palveluun. Käytä vaihtoehtoista todennustapaa tai ole yhteydessä Duon asiakaspalveluun saadaksesi apua." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." @@ -7179,7 +7260,7 @@ "message": "Päivitä salausasetuksesi uusien suojaussuositusten mukaisiksi ja vahvista tilisi suojausta." }, "kdfSettingsChangeLogoutWarning": { - "message": "Jos jatkat, kaikki aktiiviset istunnot kirjataan ulos. Sinun on kirjauduttava sisään uudelleen ja suoritettava kaksivaiheisen todennuksen määritys. Tietojesi säilyvyyden varmistamiseksi suosittelemme, että viet holvisi sisällön, ennen kuin muutat salausasetuksiasi." + "message": "Jos jatkat, kirjataan kaikki aktiiviset istunnot ulos, jonka jälkeen sinun on kirjauduttava sisään uudelleen ja suoritettava mahdollisesti määritetty kaksivaiheinen tunnistautuminen. Tietojesi säilyvyyden varmistamiseksi suosittelemme, että viet holvisi sisällön ennen salausasetustesi muuttamista." }, "secretsManager": { "message": "Salaisuushallinta" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Määritä seuraaviin kokoelmiin" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Vain näiden kokoelmien käyttöoikeuden omaavat organisaation jäsenet voivat nähdä kohteen." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Vain näiden kokoelmien käyttöoikeuden omaavat organisaation jäsenet voivat nähdä kohteet." }, "selectCollectionsToAssign": { @@ -8374,10 +8458,10 @@ "message": "Et ole valinnut yhtään kokoelmaa." }, "updateName": { - "message": "Vaihda nimi" + "message": "Muuta nimi" }, "updatedOrganizationName": { - "message": "Organisaation nimi vaihdettiin" + "message": "Organisaation nimi muutettiin" }, "providerPlan": { "message": "Hallintapalvelun toimittaja" @@ -8425,7 +8509,7 @@ "message": "Bitcoin" }, "updatedTaxInformation": { - "message": "Verotiedot vaihdettiin" + "message": "Verotiedot muutettiin" }, "unverified": { "message": "Vahvistamaton" @@ -8543,7 +8627,7 @@ "message": "Tilausmuutoksista aiheutuvat laskutussumman muutokset huomioidaan suhteutetusti kuukausilaskutuksen seuraavassa veloituksessa." }, "billingHistoryDescription": { - "message": "Lataa CSV-tiedosto nähdäksesi jokaisen laskutuspäivän asiakastiedot. Korjattuja veloituksia ei sisällytetä CSV-teidostoon ja ne saattavat poiketa liitetystä laskusta. Tarkimmat laskutustiedot näet kuukausilaskuistasi.", + "message": "Lataa CSV-tiedosto nähdäksesi jokaisen laskutuspäivän asiakastiedot. Korjattuja veloituksia ei sisällytetä CSV-tiedostoon ja ne saattavat poiketa liitetystä laskusta. Tarkimmat laskutustiedot näet kuukausilaskuistasi.", "description": "A paragraph on the Billing History page of the Provider Portal letting users know they can download a CSV report for their invoices that does not include prorations." }, "noInvoicesToList": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Valitse kansio" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ siirretään pysyvästi valittulle organisaatiolle, etkä enää omista näitä kohteita.", + "personalItemTransferWarningSingular": { + "message": "1 kohde siirretään pysyvästi valitulle organisaatiolle, jonka jälkeen et enää omista sitä." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ kohdetta siirretään pysyvästi valitulle organisaatiolle, jonka jälkeen et enää omista niitä.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ siirretään pysyvästi organisaatiolle $ORG$, etkä enää omista näitä kohteita.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 kohde siirretään pysyvästi organisaatiolle $ORG$, jonka jälkeen et enää omista sitä.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ kohdetta siirretään pysyvästi organisaatiolle $ORG$, jonka jälkeen et enää omista niitä.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,7 +8688,10 @@ } } }, + "data": { + "message": "Tiedot" + }, "purchasedSeatsRemoved": { - "message": "purchased seats removed" + "message": "ostetut käyttäpaikat poistettiin" } } diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index a5fa31a531c..59169d753da 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Burahin ang item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Nagkaproblema sa pagde-decrypt ng na-export na file. Hindi tumutugma ang encryption key mo sa ginamit pang-export sa data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Kontrol sa pag access" }, - "groupAccessAllItems": { - "message": "Maaaring ma-access at baguhin ng grupong ito ang lahat ng item." - }, - "groupAccessSelectedCollections": { - "message": "Ang grupong ito ay maaaring ma access lamang ang mga napiling koleksyon." - }, "readOnly": { "message": "Magbasa lamang" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Gumagamit ang user na ito ng dalawang hakbang na pag login upang maprotektahan ang kanilang account." }, - "userAccessAllItems": { - "message": "Maaaring ma access at baguhin ng gumagamit na ito ang lahat ng mga item." - }, - "userAccessSelectedCollections": { - "message": "Ang user na ito ay maaaring ma access lamang ang mga napiling koleksyon." - }, "search": { "message": "Maghanap" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Naimbitahan ka na sumali sa organisasyong nakalista sa itaas. Upang tanggapin ang paanyaya, kailangan mong mag log in o lumikha ng isang bagong account sa Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Tinanggap ang paanyaya" }, @@ -4377,6 +4386,9 @@ "message": "Ipadala ang link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopyahin ang Link ng Padala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "o", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try mo na ngayon", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index a10d4e41717..e233ced14cf 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Éléments déplacés vers $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Élément déplacé vers $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Supprimer l'élément" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Erreur lors du déchiffrement du fichier exporté. Votre clé de chiffrement ne correspond pas à la clé de chiffrement utilisée pour exporter les données." }, - "importDestination": { - "message": "Destination de l'import" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "En savoir plus sur vos options d'importation" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Contrôle d’accès" }, - "groupAccessAllItems": { - "message": "Ce groupe peut voir et modifier tous les éléments." - }, - "groupAccessSelectedCollections": { - "message": "Ce groupe peut accéder uniquement aux collections sélectionnées." - }, "readOnly": { "message": "Lecture seule" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Cet utilisateur utilise l'authentification à deux facteurs pour protéger son compte." }, - "userAccessAllItems": { - "message": "Cet utilisateur peut voir et modifier tous les éléments." - }, - "userAccessSelectedCollections": { - "message": "Cet utilisateur peut accéder uniquement aux collections sélectionnées." - }, "search": { "message": "Rechercher" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Vous avez été invité à rejoindre l'organisation ci-dessus. Pour accepter l'invitation, vous devez vous connecter ou créer un nouveau compte Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Terminer de rejoindre cette organisation en définissant un mot de passe principal." + }, "inviteAccepted": { "message": "Invitation acceptée" }, @@ -4377,6 +4386,9 @@ "message": "Lien du Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copier le lien" + }, "copySendLink": { "message": "Copier le lien du Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "ou", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Les équipes de développement, DevOps et IT choisissent Bitwarden Secrets Manager pour gérer et déployer en toute sécurité leurs infrastructures et leurs secrets de machine." + }, + "centralizeSecretsManagement": { + "message": "Centraliser la gestion des secrets." + }, + "centralizeSecretsManagementDescription": { + "message": "Stockez et gérez les secrets en toute sécurité à un seul endroit pour éviter un étalement secret à travers votre organisation." + }, + "preventSecretLeaks": { + "message": "Empêcher les fuites de secrets." + }, + "preventSecretLeaksDescription": { + "message": "Protégez les secrets avec le chiffrement de bout en bout. Plus de codage dur des secrets ou de partage via des fichiers .env." + }, + "enhanceDeveloperProductivity": { + "message": "Améliorer la productivité des développeurs." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Récupération et déploiement programmatiques des secrets lors de l'exécution, afin que les développeurs puissent se concentrer sur ce qui compte le plus, comme l'amélioration de la qualité du code." + }, + "strengthenBusinessSecurity": { + "message": "Renforcer la sécurité de votre entreprise." + }, + "strengthenBusinessSecurityDescription": { + "message": "Gardez un contrôle rigoureux sur l'accès machine et humain aux secrets grâce aux intégrations SSO, aux journaux d'événements et à la rotation d'accès." + }, + "tryItNow": { + "message": "Essayez-le maintenant" + }, + "sendRequest": { + "message": "Envoyer la requête" + }, + "addANote": { + "message": "Ajouter une note" + }, + "bitwardenSecretsManager": { + "message": "Secrets Manager de Bitwarden" + }, + "moreProductsFromBitwarden": { + "message": "Plus de produits de Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Demander l'accès au Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "Vous avez besoin de l'approbation de votre administrateur pour essayer Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Courriel de demande d'accès au Secrets Manager envoyé aux administrateurs." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Bonjour, \n\nJe demande un abonnement à Secrets Manager de Bitwarden pour mon équipe. Votre support serait très apprécié!\n\nSecrets Manager de Bitwarden est une solution de gestion de chiffrement bout en bout des secrets pour conserver, partager et déployer des identifiants d'appareils comme des clés d'API, des mots de passe de bases de données et des certificats d'authentification de façon sécuritaire.\n\nSecrets Manager nous aidera à :\n\n- Améliorer notre sécurité\n- Accélérer nos opérations\n- Prévenir les fuites coûteuses de nos secrets\n\nPour demander un essai gratuit pour notre équipe, veuillez contacter Bitwarden.\n\nMerci pour votre aide!" + }, + "giveMembersAccess": { + "message": "Donner accès aux membres :" + }, + "viewAndSelectTheMembers": { + "message": "voir et sélectionner les membres que vous voulez donner accès à Secrets Manager." + }, + "openYourOrganizations": { + "message": "Ouvrir votre organisation" + }, + "usingTheMenuSelect": { + "message": "À l'aide du menu, sélectionnez" + }, + "toGrantAccessToSelectedMembers": { + "message": "pour donner accès aux membres sélectionnés." + }, "sendVaultCardTryItNow": { "message": "essayez-le maintenant", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "Assigner à ces collections" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Seuls les membres de l'organisation ayant accès à ces collections pourront voir l'élément." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Seuls les membres de l'organisation ayant accès à ces collections pourront voir les éléments." }, "selectCollectionsToAssign": { "message": "Sélectionnez les collections à assigner" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Sélectionner un dossier" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ seront transférés à l'organisation sélectionnée de façon permanente. Vous ne serez plus propriétaire de ces éléments.", + "personalItemTransferWarningSingular": { + "message": "1 élément sera transféré définitivement à l'organisation sélectionnée. Vous ne serez plus le propriétaire de cet élément." + }, + "personalItemsTransferWarningPlural": { + "message": "Les éléments $PERSONAL_ITEMS_COUNT$ seront transférés de façon permanente à l'organisation sélectionnée. Vous ne serez plus le propriétaire de ces éléments.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { + "personalItemWithOrgTransferWarningSingular": { + "message": "1 élément sera transféré définitivement à $ORG$. Vous ne serez plus le propriétaire de cet élément.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { "message": "$PERSONAL_ITEMS_COUNT$ seront transférés à $ORG$ de façon permanente. Vous ne serez plus propriétaire de ces éléments.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Données" + }, "purchasedSeatsRemoved": { "message": "licenses achetées retirées" } diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 31a61b1185e..d5514bd6846 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 8fa80d92984..3cc6822c14f 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "מחק פריט" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "בקרת גישה" }, - "groupAccessAllItems": { - "message": "קבוצה זו יכולה לגשת ולשנות את כל הפריטים." - }, - "groupAccessSelectedCollections": { - "message": "קבוצה זו יכולה רק לגשת לאוספים שנבחרו." - }, "readOnly": { "message": "קריאה בלבד" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "משתמש זה הפעיל כניסה דו שלבית כדי להגן על חשבונו." }, - "userAccessAllItems": { - "message": "משתמש זה יכול לגשת ולשנות את כל הפריטים." - }, - "userAccessSelectedCollections": { - "message": "משתמש זה יכול לגשת רק לאוספים נבחרים." - }, "search": { "message": "חיפוש" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "הוזמנת להצטרף לארגון הרשום לעיל. בכדי להסכים, עליך להתחבר או ליצור חשבון Bitwarden חדש." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "ההזמנה התקבלה" }, @@ -4377,6 +4386,9 @@ "message": "לינק לSend", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "העתק לינק לSend", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 113d1a29407..2392b53cd0b 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index e681c0d6c5f..e09ad842e94 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Izbriši stavku" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Greška u dešifriranju izvozne datoteke. Ovaj ključ za šifriranje ne odgovara ključu za šifriranje korištenom pri izvozu datoteke." }, - "importDestination": { - "message": "Odredište uvoza" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Više o mogućnostima uvoza" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Kontrola pristupa" }, - "groupAccessAllItems": { - "message": "Ova grupa može pristupiti i urediti sve stavke." - }, - "groupAccessSelectedCollections": { - "message": "Ova grupa može pristupiti samo određenim zbirkama." - }, "readOnly": { "message": "Samo za čitanje" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Ovaj korisnik upotrebljava prijavu u dva koraka za zaštitu svog računa." }, - "userAccessAllItems": { - "message": "Ovaj korisnik može pristupiti i urediti sve stavke." - }, - "userAccessSelectedCollections": { - "message": "Ovaj korisnik može pristupiti samo određenim zbirkama." - }, "search": { "message": "Traži" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Primljen je poziv za pridruživanje gore navedenoj organizaciji. Za prihvaćanje poziva potrebno je prijaviti se na svoj postojeći Bitwarden račun ili stvoriti novi." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Poziv prihvaćen" }, @@ -4377,6 +4386,9 @@ "message": "Veza na Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopiraj vezu na Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "ili", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "isprobaj odmah", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 523192f3fff..5dbde9079ae 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -43,10 +43,10 @@ "message": "Kártyatulajdonos neve" }, "loginCredentials": { - "message": "Login credentials" + "message": "Bejelentkezési hitelesítések" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Hitelesítő kulcs" }, "number": { "message": "Szám" @@ -145,13 +145,13 @@ "message": "Hitelesítő kulcs (egyszeri idő alapú)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Tegyük zökkenőmentessé a kétlépcsős azonosítást." }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "A Bitwarden képes tárolni és kitölteni a kétlépcsős ellenőrző kódokat. Másoljuk ki és illesszük be a kulcsot ebbe a mezőbe." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "A Bitwarden képes tárolni és kitölteni a kétlépcsős ellenőrző kódokat. Válasszuk a kamera ikont, hogy képernyőképet készítsünk a webhely hitelesítő QR kódjáról vagy másoljuk ki és illesszük be a kulcsot ebbe a mezőbe." }, "folder": { "message": "Mappa" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Az elemek áthelyezésre kerültek: $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Az elem áthelyezésre került: $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Elem törlése" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Hiba történt az exportált fájl visszafejtése során. A titkosítási kulcs nem egyezik meg az adatok exportálásához használt titkosítási kulccsal." }, - "importDestination": { - "message": "Importálás leírás" + "destination": { + "message": "Cél" }, "learnAboutImportOptions": { "message": "Információ az importálási opciókról" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Hozzáférés vezérlés" }, - "groupAccessAllItems": { - "message": "Ez a csoport minden elemhez hozzáfér és módosíthatja azokat." - }, - "groupAccessSelectedCollections": { - "message": "Ez a csoport csak a kiválasztott gyűjteményekhez fér hozzá." - }, "readOnly": { "message": "Csak olvasható" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Ez a felhasználó kétlépcsős bejelentkezést használ fiókja védelmére." }, - "userAccessAllItems": { - "message": "Ez a felhasználó minden elemhez hozzáfér és módosítani tudja azokat." - }, - "userAccessSelectedCollections": { - "message": "Ez a felhasználó csak a kiválasztott gyűjteményekhez fér hozzá." - }, "search": { "message": "Keresés" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Meghívást érkezett a fenti szervezethez csatlakozáshoz. A meghívás elfogadásához be kell jelentkezni vagy új Bitwarden fiókot kell létrehozni." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Fejezzük be a szervezethez csatlakozást egy mesterjelszó beállításával." + }, "inviteAccepted": { "message": "A meghívás elfogadásra került." }, @@ -4377,6 +4386,9 @@ "message": "Send hivatkozás", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send hivatkozás másolása", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "vagy", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "próbáljuk ki most", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "Hozzárendelés ezen gyűjteményekhez" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Csak az ezekhez a gyűjteményekhez hozzáféréssel rendelkező szervezeti tagok láthatják az elemet." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Csak az ezekhez a gyűjteményekhez hozzáféréssel rendelkező szervezeti tagok láthatják az elemeket." }, "selectCollectionsToAssign": { "message": "Hozzárendelendő gyűjtemények kiválasztása" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Mappa kiválasztása" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ véglegesen átkerül a kiválasztott szervezethez. A továbbiakban nem leszünk a tulajdonosa ezeknek az elemeknek.", + "personalItemTransferWarningSingular": { + "message": "1 elem véglegesen átkerül a kiválasztott szervezethez. A továbbiakban nem leszünk az elem tulajdonosa." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ véglegesen átkerül a kiválasztott szervezethez. A továbbiakban nem leszünk az elemek tulajdonosa.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { + "personalItemWithOrgTransferWarningSingular": { + "message": "1 véglegesen átkerül $ORG$ szervezeti egységbe. A továbbiakban nem leszünk a tulajdonosa ennek az elemnek.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { "message": "$PERSONAL_ITEMS_COUNT$ véglegesen átkerül $ORG$ szervezeti egységbe. A továbbiakban nem leszünk a tulajdonosa ezeknek az elemeknek.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Adat" + }, "purchasedSeatsRemoved": { "message": "megvásárolt hely eltávolításra került." } diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 8d4babe7348..e7b2870fe78 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Hapus Item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Tidak dapat mendekripsi file yang diekspor. Kunci enkripsi Anda tidak cocok dengan kunci enkripsi yang digunakan untuk menekspor data terkait." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Kontrol akses" }, - "groupAccessAllItems": { - "message": "Grup ini dapat mengakses dan mengubah semua item." - }, - "groupAccessSelectedCollections": { - "message": "Grup ini hanya dapat mengakses koleksi yang dipilih." - }, "readOnly": { "message": "Baca Saja" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Pengguna ini menggunakan proses masuk dua langkah untuk melindungi akun mereka." }, - "userAccessAllItems": { - "message": "Pengguna ini dapat mengakses dan mengubah semua item." - }, - "userAccessSelectedCollections": { - "message": "Pengguna ini hanya dapat mengakses koleksi yang dipilih." - }, "search": { "message": "Cari" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Anda telah diundang untuk bergabung dengan organisasi yang tercantum di atas. Untuk menerima undangan, Anda harus masuk atau membuat akun Bitwarden baru." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Undangan Diterima" }, @@ -4377,6 +4386,9 @@ "message": "Kirim Tautan", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Salin Kirim Tautan", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "atau", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "coba sekarang", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index fc3fcd0f06d..5da4256e40d 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Elimina elemento" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Errore durante la decrittografia del file esportato. La chiave di crittografia non corrisponde alla chiave di crittografia usata per esportare i dati." }, - "importDestination": { - "message": "Destinazione dell'importazione" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Ulteriori informazioni sulle tue opzioni di importazione" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Controllo accesso" }, - "groupAccessAllItems": { - "message": "Questo gruppo può accedere e modificare tutti gli elementi." - }, - "groupAccessSelectedCollections": { - "message": "Questo gruppo può accedere solo alle raccolte selezionate." - }, "readOnly": { "message": "Sola lettura" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Questo utente usa la verifica in due passaggi per proteggere il suo account." }, - "userAccessAllItems": { - "message": "Questo utente può accedere e modificare tutti gli elementi." - }, - "userAccessSelectedCollections": { - "message": "Questo utente può accedere solo alle raccolte selezionate." - }, "search": { "message": "Cerca" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Sei stato invitato a far parte dell'organizzazione qui sopra. Per accettare l'invito, accedi o crea un nuovo account Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invito accettato" }, @@ -4377,6 +4386,9 @@ "message": "Link del Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copia link del Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "o", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "provalo adesso", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assegna a queste raccolte" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 1eb81bb6a02..9148f85ecb1 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -43,10 +43,10 @@ "message": "カードの名義人名" }, "loginCredentials": { - "message": "Login credentials" + "message": "ログイン情報" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "認証キー" }, "number": { "message": "番号" @@ -145,13 +145,13 @@ "message": "認証キー (TOTP)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "2段階認証をシームレスにする" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden は2段階認証コードを保存・入力できます。この欄にキーをコピーして貼り付けてください。" }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden は2段階認証コードを保存・入力できます。 カメラアイコンを選択して、このウェブサイトの認証 QR コードのスクリーンショットを撮るか、キーをコピーしてこのフィールドに貼り付けてください。" }, "folder": { "message": "フォルダー" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "アイテムを $ORGNAME$ に移動しました", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "アイテムを $ORGNAME$ に移動しました", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "アイテムの削除" }, @@ -628,16 +646,16 @@ "message": "ログインセッションの有効期限が切れています。" }, "restartRegistration": { - "message": "Restart registration" + "message": "登録を再度始める" }, "expiredLink": { - "message": "Expired link" + "message": "期限切れのリンク" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "登録を再度始めるか、ログインしてください。" }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "すでにアカウントを持っている可能性があります" }, "logOutConfirmation": { "message": "ログアウトしてもよろしいですか?" @@ -1087,7 +1105,7 @@ "message": "本当に続行しますか?" }, "moveSelectedItemsDesc": { - "message": "Choose a folder that you would like to add the $COUNT$ selected item(s) to.", + "message": "$COUNT$個のアイテムを追加したいフォルダーを選択してください。", "placeholders": { "count": { "content": "$1", @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "エクスポートされたファイルの復号でエラーが発生しました。暗号化キーが、データをエクスポートするために使用された暗号化キーと一致しません。" }, - "importDestination": { - "message": "インポート先" + "destination": { + "message": "保存先" }, "learnAboutImportOptions": { "message": "インポートオプションについて学ぶ" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "アクセスコントロール" }, - "groupAccessAllItems": { - "message": "全てのアイテムの読み取り・編集" - }, - "groupAccessSelectedCollections": { - "message": "選択コレクション内のアクセス" - }, "readOnly": { "message": "読み取り専用" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "このユーザーはアカウントを保護するため二段階認証を利用しています。" }, - "userAccessAllItems": { - "message": "全てのアイテムの読み取り・編集" - }, - "userAccessSelectedCollections": { - "message": "選択コレクション内のアクセス" - }, "search": { "message": "検索" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "あなたは上記の組織への参加の招待を受けています。招待を承諾するには、ログインするかBitwardenアカウントを作成してください。" }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "マスターパスワードを設定して、この組織への参加を完了します。" + }, "inviteAccepted": { "message": "招待が承諾されました。" }, @@ -3811,7 +3820,7 @@ "message": "何も選択されていません。" }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Bitwarden からメールでアドバイスやお知らせ、リサーチの機会を受け取りましょう。" }, "unsubscribe": { "message": "配信停止" @@ -4377,6 +4386,9 @@ "message": "Send リンク", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "リンクをコピー" + }, "copySendLink": { "message": "Send リンクをコピー", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "または", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "開発チーム、DevOps チームは、インフラストラクチャとマシンのシークレットを安全に管理および展開するために Bitwarden シークレットマネージャーを選択します。" + }, + "centralizeSecretsManagement": { + "message": "シークレット管理を一元化します。" + }, + "centralizeSecretsManagementDescription": { + "message": "組織全体のシークレットのスプロールを防ぐために、1つの場所にシークレットを安全に保管して管理します。" + }, + "preventSecretLeaks": { + "message": "シークレットの漏洩を防ぎます。" + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "試してみてください", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "これらのコレクションに割り当てる" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "これらのコレクションにアクセスできる組織メンバーのみがアイテムを見ることができます。" + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "これらのコレクションにアクセスできる組織メンバーのみがアイテムを見ることができます。" }, "selectCollectionsToAssign": { "message": "割り当てるコレクションを選択" @@ -8559,7 +8643,7 @@ "description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions, please contact Bitwarden support'. 'Bitwarden' should not be translated" }, "sponsored": { - "message": "Sponsored" + "message": "スポンサー提供" }, "licenseAndBillingManagementDesc": { "message": "Bitwarden クラウドサーバーで更新を行った後、ライセンスファイルをアップロードして最新の変更を適用してください。" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "フォルダーを選択" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ は選択した組織に恒久的に移行されます。これらのアイテムはあなたの所有ではなくなります。", + "personalItemTransferWarningSingular": { + "message": "1個のアイテムは選択した組織に恒久的に移行されます。このアイテムはあなたの所有ではなくなります。" + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 個のアイテムは選択した組織に恒久的に移行されます。これらのアイテムはあなたの所有ではなくなります。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ は $ORG$ に恒久的に移行されます。これらのアイテムはあなたの所有ではなくなります。", + "personalItemWithOrgTransferWarningSingular": { + "message": "1個のアイテムは $ORG$ に恒久的に移行されます。このアイテムはあなたの所有ではなくなります。", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 個のアイテムは $ORG$ に恒久的に移行されます。これらのアイテムはあなたの所有ではなくなります。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "データ" + }, "purchasedSeatsRemoved": { "message": "購入済みシートが削除されました" } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index d34d19e693f..f07365fc141 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "წაშლილი საგნები" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index 31a61b1185e..d5514bd6846 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index 5e04b927407..c0da99f19dc 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "ಐಟಂ ಅಳಿಸಿ" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "ರಫ್ತು ಮಾಡಿದ ಫೈಲ್ ಅನ್ನು ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡುವಲ್ಲಿ ದೋಷ. ಡೇಟಾವನ್ನು ರಫ್ತು ಮಾಡಲು ಬಳಸಿದ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಕೀಗೆ ನಿಮ್ಮ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಕೀ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "ಪ್ರವೇಶ ನಿಯಂತ್ರಣ" }, - "groupAccessAllItems": { - "message": "ಈ ಗುಂಪು ಎಲ್ಲಾ ವಸ್ತುಗಳನ್ನು ಪ್ರವೇಶಿಸಬಹುದು ಮತ್ತು ಮಾರ್ಪಡಿಸಬಹುದು." - }, - "groupAccessSelectedCollections": { - "message": "ಈ ಗುಂಪು ಆಯ್ದ ಸಂಗ್ರಹಗಳನ್ನು ಮಾತ್ರ ಪ್ರವೇಶಿಸಬಹುದು." - }, "readOnly": { "message": "ಓದಲು ಮಾತ್ರ" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "ಈ ಬಳಕೆದಾರರು ತಮ್ಮ ಖಾತೆಯನ್ನು ರಕ್ಷಿಸಲು ಎರಡು-ಹಂತದ ಲಾಗಿನ್ ಅನ್ನು ಬಳಸುತ್ತಿದ್ದಾರೆ." }, - "userAccessAllItems": { - "message": "ಈ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ವಸ್ತುಗಳನ್ನು ಪ್ರವೇಶಿಸಬಹುದು ಮತ್ತು ಮಾರ್ಪಡಿಸಬಹುದು." - }, - "userAccessSelectedCollections": { - "message": "ಈ ಬಳಕೆದಾರರು ಆಯ್ದ ಸಂಗ್ರಹಗಳನ್ನು ಮಾತ್ರ ಪ್ರವೇಶಿಸಬಹುದು." - }, "search": { "message": "ಹುಡುಕಿ" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "ಮೇಲೆ ಪಟ್ಟಿ ಮಾಡಲಾದ ಸಂಸ್ಥೆಗೆ ಸೇರಲು ನಿಮ್ಮನ್ನು ಆಹ್ವಾನಿಸಲಾಗಿದೆ. ಆಹ್ವಾನವನ್ನು ಸ್ವೀಕರಿಸಲು, ನೀವು ಲಾಗ್ ಇನ್ ಆಗಬೇಕು ಅಥವಾ ಹೊಸ ಬಿಟ್‌ವಾರ್ಡನ್ ಖಾತೆಯನ್ನು ರಚಿಸಬೇಕು." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "ಆಮಂತ್ರಣವನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ" }, @@ -4377,6 +4386,9 @@ "message": "ಲಿಂಕ್ ಕಳುಹಿಸಿ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "ಲಿಂಕ್ ಕಳುಹಿಸಿ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "ಅಥವ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "ಅದನ್ನೀಗ ಪ್ರಯತ್ನಿಸಿ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index e92a2a4ecf4..40639d221c6 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "항목 삭제" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "내보내려는 파일을 복호화하던 중 오류가 발생했습니다. 암호화 키가 내보내려는 데이터를 암호화한 키와 일치하지 않습니다." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "가져오기 설정 알아보기" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "접근 제어" }, - "groupAccessAllItems": { - "message": "이 그룹은 모든 항목에 액세스하고 수정할 수 있습니다." - }, - "groupAccessSelectedCollections": { - "message": "이 그룹은 선택된 컬렉션에만 액세스할 수 있습니다." - }, "readOnly": { "message": "읽기 전용" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "이 사용자는 계정을 보호하기 위해 2단계 로그인을 사용하고 있습니다." }, - "userAccessAllItems": { - "message": "이 사용자는 모든 항목에 액세스하고 수정할 수 있습니다." - }, - "userAccessSelectedCollections": { - "message": "이 사용자는 선택된 컬렉션에만 액세스할 수 있습니다." - }, "search": { "message": "검색" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "이 조직에서 귀하에게 가입 초대를 보냈습니다. 초대를 수락하려면 로그인하거나 Bitwarden 계정을 생성해야 합니다." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "초대 수락됨" }, @@ -4377,6 +4386,9 @@ "message": "Send 링크", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send 링크 복사", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "지금", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "체험해보세요", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 8a28a838240..b072abd88b5 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Izdzēst vienumu" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Kļūda izguves datnes atšifrēšanā. Izmantotā atslēga neatbilst tai, kas tika izmantota satura izgūšanai." }, - "importDestination": { - "message": "Ievietošanas galamērķis" + "destination": { + "message": "Galamērķis" }, "learnAboutImportOptions": { "message": "Uzzināt par ievietošanas iespējām" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Piekļuves pārraudzība" }, - "groupAccessAllItems": { - "message": "Šī kopa var piekļūt visiem vienumiem un mainīt tos." - }, - "groupAccessSelectedCollections": { - "message": "Šī kopa var piekļūt tikai izvēlētajiem krājumiem." - }, "readOnly": { "message": "Tikai lasāms" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Šis lietotājs izmanto divpakāpju pieteikšanos, lai aizsargātu savu kontu." }, - "userAccessAllItems": { - "message": "Šis lietotājs var piekļūt visiem vienumiem un mainīt tos." - }, - "userAccessSelectedCollections": { - "message": "Šis lietotājs var piekļūt tikai pie atlasītajiem krājumiem." - }, "search": { "message": "Meklēt" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Tu esi uzaicināts pievienoties augstāk norādītajai apvienībai. Lai to pieņemtu, jāpiesakās vai jāizveido jauns Bitwarden konts." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Uzaicinājums pieņemts" }, @@ -4377,6 +4386,9 @@ "message": "Send saite", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Ievietot Send saiti starpliktuvē", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "vai", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "izmēģināt tagad", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Piešķirt šiem krājumiem" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Vienumu varēs redzēt tikai apvnienības dalībnieki ar piekļuvi šiem krājumiem." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Vienumus varēs redzēt tikai apvnienības dalībnieki ar piekļuvi šiem krājumiem." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Atlasīt mapi" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ tiks neatgriezeniski nodoti atlasītajai apvienībai. Šie vienumi Tev vairs nepiederēs.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ tiks neatgriezeniski nodoti $ORG$. Šie vienumi Tev vairs nepiederēs.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Dati" + }, "purchasedSeatsRemoved": { "message": "iegādātās vietas noņemtas" } diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index 137a78e0e2e..23c03780af5 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "ഇനം ഇല്ലാതാക്കുക " }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "പ്രവേശന നിയന്ത്രണം" }, - "groupAccessAllItems": { - "message": "ഈ ഗ്രൂപ്പിന്എല്ലാ ഇനങ്ങളും ആക്‌സസ് ചെയ്യാനും പരിഷ്‌ക്കരിക്കാനും കഴിയും." - }, - "groupAccessSelectedCollections": { - "message": "തിരഞ്ഞെടുത്ത കളക്ഷനുകൾ മാത്രമേ ഈ ഗ്രൂപ്പിന് ആക്‌സസ് ചെയ്യാൻ കഴിയൂ." - }, "readOnly": { "message": "വായിക്കാൻ മാത്രം" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "ഈ ഉപയോക്താവ് അവരുടെ അക്കൗണ്ട് രണ്ട്-പ്രവേശനം ഉപയോഗിച്ച് സുരക്ഷിതമാക്കിയിരിക്കുന്നു." }, - "userAccessAllItems": { - "message": "ഈ ഉപയോക്താവിന് എല്ലാ ഇനങ്ങളും ആക്‌സസ് ചെയ്യാനും പരിഷ്‌ക്കരിക്കാനും കഴിയും." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "തിരയുക" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "ക്ഷണം സ്വീകരിച്ചു" }, @@ -4377,6 +4386,9 @@ "message": "ലിങ്ക് അയയ്‌ക്കുക", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send ലിങ്ക് പകർത്തുക", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index 31a61b1185e..d5514bd6846 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index 31a61b1185e..d5514bd6846 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index 31e8c793d56..f1adef825fa 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Slett element" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Feil under dekryptering av den eksporterte filen. Krypteringsnøkkelen samsvarte ikke med krypteringsnøkkelen som ble brukt eksport av data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Tilgangsstyring" }, - "groupAccessAllItems": { - "message": "Denne gruppen kan få tilgang til og endre alle elementer." - }, - "groupAccessSelectedCollections": { - "message": "Denne gruppen har bare tilgang til de valgte samlingene." - }, "readOnly": { "message": "Skrivebeskyttet" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Denne brukeren bruker 2-trinnsinnlogging til å beskytte kontoen sin." }, - "userAccessAllItems": { - "message": "Denne brukeren kan få tilgang til og endre alle elementer." - }, - "userAccessSelectedCollections": { - "message": "Denne brukeren har bare tilgang til de valgte samlingene." - }, "search": { "message": "Søk" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Du har blitt invitert til å bli med i organisasjonen som er listet opp ovenfor. For å godkjenne invitasjonen, må du enten logge på eller lage en ny Bitwarden-konto." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitasjonen ble godkjent" }, @@ -4377,6 +4386,9 @@ "message": "Send lenke", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopier Send-lenke", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "eller", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "prøv det nå", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index 79f2ed80be6..720e44b29ee 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 5ac8df11bf0..107f64a5414 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items verplaatst naar $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item verplaatst naar $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Item verwijderen" }, @@ -628,16 +646,16 @@ "message": "Je inlogsessie is verlopen." }, "restartRegistration": { - "message": "Restart registration" + "message": "Registratie herstarten" }, "expiredLink": { - "message": "Expired link" + "message": "Verlopen link" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Herstart de registratie of probeer in te loggen." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Je hebt al een account" }, "logOutConfirmation": { "message": "Weet je zeker dat je wilt uitloggen?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Fout bij het decoderen van het geëxporteerde bestand. Je encryptiesleutel komt niet overeen met de gebruikte sleutel waarmee de gegevens zijn geëxporteerd." }, - "importDestination": { - "message": "Importbestemming" + "destination": { + "message": "Bestemming" }, "learnAboutImportOptions": { "message": "Leer meer over je importopties" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Toegangsbeheer" }, - "groupAccessAllItems": { - "message": "Deze groep kan alle items inzien en bewerken." - }, - "groupAccessSelectedCollections": { - "message": "Deze groep heeft alleen toegang tot de geselecteerde verzamelingen." - }, "readOnly": { "message": "Alleen-lezen" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Het account van deze gebruiker is beschermd met tweestapsaanmelding." }, - "userAccessAllItems": { - "message": "Deze gebruiker kan alle items inzien en bewerken." - }, - "userAccessSelectedCollections": { - "message": "Deze gebruiker heeft alleen toegang tot de geselecteerde verzamelingen." - }, "search": { "message": "Zoeken" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Je bent uitgenodigd om lid te worden van bovenstaande organisatie. Om de uitnodiging te accepteren, moet je inloggen of een nieuw Bitwarden-account aanmaken." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Voltooi je lidmaatschap aan deze organisatie door een hoofdwachtwoord in te stellen." + }, "inviteAccepted": { "message": "Uitnodiging geaccepteerd" }, @@ -3811,7 +3820,7 @@ "message": "Je hebt niets geselecteerd." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Krijg advies, aankondigingen en onderzoeksmogelijkheden van Bitwarden in je inbox." }, "unsubscribe": { "message": "Afmelden" @@ -4377,6 +4386,9 @@ "message": "Send-koppeling", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Link kopiëren" + }, "copySendLink": { "message": "Send-koppeling kopiëren", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "of", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Ontwikkeling-, DevOps- en IT-teams kiezen voor Bitwarden Secrets Manager om hun infrastructuur en secrets veilig te beheren en te implementeren." + }, + "centralizeSecretsManagement": { + "message": "Beheer van secrets centraliseren." + }, + "centralizeSecretsManagementDescription": { + "message": "Secrets veilig opslaan en beheren op één locatie om te voorkomen dat secrets overal in je organisatie rondslingeren." + }, + "preventSecretLeaks": { + "message": "Lekken van secrets voorkomen." + }, + "preventSecretLeaksDescription": { + "message": "Secrets beveiligen met end-to-end versleuteling. Nooit meer secrets hardcoderen of delen via .env-bestanden." + }, + "enhanceDeveloperProductivity": { + "message": "Ontwikkelaarsproductiviteit verbeteren." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatisch ophalen en implementeren van secrets tijdens runtime zodat ontwikkelaars zich kunnen richten op wat het belangrijkst is, zoals het verbeteren van de kwaliteit van de code." + }, + "strengthenBusinessSecurity": { + "message": "Bedrijfsveiligheid versterken." + }, + "strengthenBusinessSecurityDescription": { + "message": "Houd strakke controle over de toegang van machines en mensen tot secrets met SSO-integraties, gebeurtenislogboeken en het roteren van toegang." + }, + "tryItNow": { + "message": "Probeer het nu" + }, + "sendRequest": { + "message": "Verzoek versturen" + }, + "addANote": { + "message": "Notitie toevoegen" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "Meer producten van Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Toegang tot Secrets Manager aanvragen" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "Je hebt toestemming van je beheerder nodig om Secrets Manager te proberen." + }, + "smAccessRequestEmailSent": { + "message": "Toegangsverzoek voor secrets manager via e-mail verzonden naar beheerders." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hallo,\n\nIk vraag hierbij om een abonnement op Bitwarden Secrets Manager voor ons team. Jouw steun zou heel wat betekenen!\n\nBitwarden Secrets Manager is een end-to-end versleutelingsoplossing voor secrets management voor het veilig opslaan, delen en implementeren van inloggegevens zoals API-sleutels, database-wachtwoorden en authenticatiecertificaten.\n\nSecrets Manager zal ons helpen met:\n\n- Veiligheid verbeteren\n- Operatie stroomlijnen\n- Kostbare lekken van secrets voorkomen\n\nNeem contact op met Bitwarden voor het aanvragen van een gratis proefperiode voor ons team.\n\nBedankt voor je hulp!" + }, + "giveMembersAccess": { + "message": "Toegang geven aan leden:" + }, + "viewAndSelectTheMembers": { + "message": "bekijk en selecteer de leden die je toegang tot Secrets Manager wilt geven." + }, + "openYourOrganizations": { + "message": "Open je organisatie's" + }, + "usingTheMenuSelect": { + "message": "Via het menu, selecteer" + }, + "toGrantAccessToSelectedMembers": { + "message": "om toegang te geven aan geselecteerde leden." + }, "sendVaultCardTryItNow": { "message": "probeer het nu", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,8 +7996,11 @@ "assignToTheseCollections": { "message": "Aan deze collecties toewijzen" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Alleen organisatieleden met toegang tot deze collecties kunnen de items zien." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Alleen organisatieleden met toegang tot deze collecties kunnen de items zien." }, "selectCollectionsToAssign": { "message": "Collecties voor toewijzen selecteren" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Map selecteren" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ worden permanent overgedragen aan de geselecteerde organisatie. Je bent niet langer de eigenaar van deze items.", + "personalItemTransferWarningSingular": { + "message": "1 item wordt permanent overgedragen aan de geselecteerde organisatie. Je bent niet langer de eigenaar van dit item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items worden permanent overgedragen aan de geselecteerde organisatie. Je bent niet langer de eigenaar van deze items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ wordt permanent overgedragen aan $ORG$. Je bent niet langer de eigenaar van deze items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item wordt permanent overgedragen aan $ORG$. Je bent niet langer de eigenaar van dit item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items worden permanent overgedragen aan $ORG$. Je bent niet langer de eigenaar van deze items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Gegevens" + }, "purchasedSeatsRemoved": { "message": "gekochte plaatsen verwijderd" } diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index 0aeb90abb74..158e5de318c 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Sletta oppføring" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Leita" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index 31a61b1185e..d5514bd6846 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 5cd49c6e2ad..76a0c78415a 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Elementy przeniesione do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Element przeniesiony do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Usuń element" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Wystąpił błąd podczas odszyfrowywania pliku. Klucz szyfrowania nie pasuje do klucza użytego podczas eksportowania danych." }, - "importDestination": { - "message": "Miejsce docelowe importu" + "destination": { + "message": "Miejsce docelowe" }, "learnAboutImportOptions": { "message": "Dowiedz się o opcjach importu" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Kontrola dostępu" }, - "groupAccessAllItems": { - "message": "Ta grupa może otwierać i modyfikować wszystkie elementy." - }, - "groupAccessSelectedCollections": { - "message": "Ta grupa posiada dostęp wyłącznie do wybranych kolekcji." - }, "readOnly": { "message": "Tylko do odczytu" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Ten użytkownik korzysta z logowania dwustopniowego, aby chronić swoje konto." }, - "userAccessAllItems": { - "message": "Ten użytkownik może otwierać i modyfikować wszystkie elementy." - }, - "userAccessSelectedCollections": { - "message": "Ten użytkownik posiada dostęp wyłącznie do wybranych kolekcji." - }, "search": { "message": "Szukaj" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Zostałeś zaproszony do dołączenia do poniższej organizacji. Aby zaakceptować zaproszenie, musisz zalogować się lub utworzyć nowe konto Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Zakończ dołączanie do tej organizacji przez ustawienie hasła głównego." + }, "inviteAccepted": { "message": "Zaproszenie zostało zaakceptowane" }, @@ -4377,6 +4386,9 @@ "message": "Link wysyłki", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Kopiuj link" + }, "copySendLink": { "message": "Kopiuj link wysyłki", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "lub", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralizuj zarządzanie sekretami." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Zapobiegaj wyciekom sekretów." + }, + "preventSecretLeaksDescription": { + "message": "Chroń sekrety szyfrowaniem end-to-end. Nigdy więcej wpisanych na sztywno sekretów ani udostępniania ich za pośrednictwem plików .env." + }, + "enhanceDeveloperProductivity": { + "message": "Zwiększ wydajność programistów." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programowo pobieraj i wdrażaj sekrety w czasie pracy, aby programiści mogli skupić się na tym, co ma największe znaczenie, jak poprawa jakości kodu." + }, + "strengthenBusinessSecurity": { + "message": "Wzmocnienie bezpieczeństwa przedsiębiorstwa." + }, + "strengthenBusinessSecurityDescription": { + "message": "Zachowaj ścisłą kontrolę nad maszynami i dostępem ludzi do sekretów z integracją SSO, dziennikami wydarzeń i rotacją dostępu." + }, + "tryItNow": { + "message": "Wypróbuj teraz" + }, + "sendRequest": { + "message": "Wyślij zgłoszenie" + }, + "addANote": { + "message": "Dodaj notatkę" + }, + "bitwardenSecretsManager": { + "message": "Menedżer sekretów Bitwarden" + }, + "moreProductsFromBitwarden": { + "message": "Więcej produktów od Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Poproś o dostęp do menedżera sekretów" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "Potrzebujesz zgody swojego administratora, aby wypróbować menedżera sekretów." + }, + "smAccessRequestEmailSent": { + "message": "E-mail z prośbą o dostęp do menedżera sekretów wiadomości został wysłany do administratorów." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Daj użytkownikom dostęp do:" + }, + "viewAndSelectTheMembers": { + "message": "zobacz i wybierz członków, którym chcesz dać dostęp do menedżera sekretów." + }, + "openYourOrganizations": { + "message": "Otwórz swoją organizację" + }, + "usingTheMenuSelect": { + "message": "Używając menu, wybierz" + }, + "toGrantAccessToSelectedMembers": { + "message": "aby przyznać dostęp wybranym członkom." + }, "sendVaultCardTryItNow": { "message": "wypróbuj teraz", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Przypisz do tych kolekcji" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Tylko członkowie organizacji z dostępem do tych kolekcji będą mogli zobaczyć ten element." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Tylko członkowie organizacji z dostępem do tych kolekcji będą mogli zobaczyć te elementy." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Wybierz folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ zostanie trwale przeniesiony do wybranej organizacji. Nie będziesz już posiadać tych elementów.", + "personalItemTransferWarningSingular": { + "message": "1 element zostanie trwale przeniesiony do wybranej organizacji. Nie będziesz już posiadać tego elementu." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ elementów zostanie trwale przeniesionych do wybranej organizacji. Nie będziesz już posiadać tych elementów.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ zostanie trwale przeniesiony do $ORG$. Nie będziesz już właścicielem tych elementów.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 przedmiot zostanie trwale przeniesiony do $ORG$. Nie będziesz już posiadać tego przedmiotu.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ elementy zostaną trwale przeniesione do $ORG$. Nie będziesz już posiadać tych elementów.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Dane" + }, "purchasedSeatsRemoved": { "message": "zakupione miejsca usunięte" } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index f07cc298931..ea7a71af8d6 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -43,10 +43,10 @@ "message": "Nome do titular do cartão" }, "loginCredentials": { - "message": "Login credentials" + "message": "Credenciais de login" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Chave do autenticador" }, "number": { "message": "Número" @@ -145,13 +145,13 @@ "message": "Chave de Autenticação (TOTP)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Tornar a verificação em duas etapas fácil" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "O Bitwarden pode armazenar e preencher códigos de verificação de duas etapas. Copie e cole a chave neste campo." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "O Bitwarden pode armazenar e preencher códigos de verificação de duas etapas. Selecione o ícone de câmera para tirar uma captura da tela do código QR de autenticador deste site, ou copie e cole a chave neste campo." }, "folder": { "message": "Pasta" @@ -189,7 +189,7 @@ "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { - "message": "You", + "message": "Você", "description": "Used as a label to indicate that the user is the owner of an item." }, "addFolder": { @@ -421,13 +421,13 @@ "message": "Item" }, "itemDetails": { - "message": "Item details" + "message": "Detalhes do item" }, "itemName": { - "message": "Item name" + "message": "Nome do item" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "Você não pode remover coleções com permissões de Somente leitura: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Excluir Item" }, @@ -628,16 +646,16 @@ "message": "A sua sessão expirou." }, "restartRegistration": { - "message": "Restart registration" + "message": "Reiniciar registro" }, "expiredLink": { - "message": "Expired link" + "message": "Link expirado" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Por favor, reinicie o registro ou tente fazer login." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Você pode já ter uma conta" }, "logOutConfirmation": { "message": "Você tem certeza que deseja sair?" @@ -814,7 +832,7 @@ "message": "Dica da senha mestra" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Se você esquecer sua senha, a dica da senha pode ser enviada ao seu e-mail. $CURRENT$/$MAXIMUM$ caracteres máximos.", "placeholders": { "current": { "content": "$1", @@ -882,7 +900,7 @@ "message": "Endereço de e-mail" }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Seu cofre está bloqueado" }, "uuid": { "message": "UUID" @@ -1009,17 +1027,17 @@ "message": "Aplicativo de autenticação" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Insira um código gerado por um aplicativo autenticador como o Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP security key" + "message": "Chave de segurança Yubico OTP" }, "yubiKeyDesc": { "message": "Utilize uma YubiKey para acessar a sua conta. Funciona com YubiKey 4, 4 Nano, 4C, e dispositivos NEO." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Insira um código gerado pelo Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1045,7 +1063,7 @@ "message": "E-mail" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "Digite o código enviado para seu e-mail." }, "continue": { "message": "Continuar" @@ -1087,7 +1105,7 @@ "message": "Tem certeza que deseja continuar?" }, "moveSelectedItemsDesc": { - "message": "Choose a folder that you would like to add the $COUNT$ selected item(s) to.", + "message": "Escolha a pasta para a qual você deseja mover os $COUNT$ itens selecionados.", "placeholders": { "count": { "content": "$1", @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Erro ao descriptografar o arquivo exportado. Sua chave de criptografia não corresponde à chave de criptografia usada para exportar os dados." }, - "importDestination": { - "message": "Destino da Importação" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Saiba mais sobre suas opções de importação" @@ -1686,19 +1704,19 @@ "message": "Insira a sua senha mestra para modificar as configurações de login em duas etapas." }, "twoStepAuthenticatorInstructionPrefix": { - "message": "Download an authenticator app such as" + "message": "Baixe um app autenticador como" }, "twoStepAuthenticatorInstructionInfix1": { "message": "," }, "twoStepAuthenticatorInstructionInfix2": { - "message": "or" + "message": "ou" }, "twoStepAuthenticatorInstructionSuffix": { "message": "." }, "continueToExternalUrlTitle": { - "message": "Continue to $URL$?", + "message": "Continuar para $URL$?", "placeholders": { "url": { "content": "$1", @@ -1707,25 +1725,25 @@ } }, "continueToExternalUrlDesc": { - "message": "You are leaving Bitwarden and launching an external website in a new window." + "message": "Você está saindo do Bitwarden e lançando um site externo em uma nova janela." }, "twoStepContinueToBitwardenUrlTitle": { - "message": "Continue to bitwarden.com?" + "message": "Continuar para bitwarden.com?" }, "twoStepContinueToBitwardenUrlDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website." + "message": "O Bitwarden Authenticator permite que você armazene as chaves de autenticador e gera códigos TOTP para fluxos de verificação de 2 etapas. Saiba mais no site bitwarden.com." }, "twoStepAuthenticatorScanCodeV2": { - "message": "Scan the QR code below with your authenticator app or enter the key." + "message": "Leia o código QR abaixo com o seu app de autenticação ou insira a chave." }, "twoStepAuthenticatorQRCanvasError": { - "message": "Could not load QR code. Try again or use the key below." + "message": "Não foi possível carregar o código QR. Tente novamente ou use a chave abaixo." }, "key": { "message": "Chave" }, "twoStepAuthenticatorEnterCodeV2": { - "message": "Verification code" + "message": "Código de verificação" }, "twoStepAuthenticatorReaddDesc": { "message": "Caso você precise adicioná-lo a outro dispositivo, abaixo está o código QR (ou chave) exigido pelo aplicativo autenticador." @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Controle de Acesso" }, - "groupAccessAllItems": { - "message": "Este grupo pode acessar e modificar todos os itens." - }, - "groupAccessSelectedCollections": { - "message": "Este grupo pode acessar apenas as coleções selecionadas." - }, "readOnly": { "message": "Somente Leitura" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Este usuário está usando o login em duas etapas para proteger a sua conta." }, - "userAccessAllItems": { - "message": "Este usuário pode acessar e modificar todos os itens." - }, - "userAccessSelectedCollections": { - "message": "Este usuário pode acessar apenas as coleções selecionadas." - }, "search": { "message": "Pesquisar" }, @@ -3430,7 +3436,7 @@ "message": "O seu e-mail foi verificado." }, "emailVerifiedV2": { - "message": "Email verified" + "message": "E-mail verificado" }, "emailVerifiedFailed": { "message": "Não é possível confirmar o seu e-mail. Tente enviar um novo e-mail de verificação." @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Você foi convidado para participar da organização listada acima. Para aceitar o convite, você precisa iniciar sessão ou criar uma nova conta no Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Convite Aceito" }, @@ -3739,7 +3748,7 @@ } }, "subscriptionSeatMaxReached": { - "message": "You cannot invite more than $COUNT$ members without increasing your subscription seats.", + "message": "Você não pode convidar mais de $COUNT$ membro(s) sem atualizar seu plano.", "placeholders": { "count": { "content": "$1", @@ -3811,7 +3820,7 @@ "message": "Você selecionou nada." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Obtenha conselhos, novidades, e oportunidades de pesquisa do Bitwarden em sua caixa de entrada." }, "unsubscribe": { "message": "Cancelar subscrição" @@ -4219,7 +4228,7 @@ "message": "Esta janela será fechada automaticamente em 5 segundos" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Você pode fechar esta janela" }, "includeAllTeamsFeatures": { "message": "Recursos para Todas as Equipes, além de:" @@ -4377,6 +4386,9 @@ "message": "Link do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copiar Link do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "ou", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "teste agora", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -5547,7 +5628,7 @@ "message": "O código de verificação é necessário." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "A autenticação foi cancelada ou demorou muito. Por favor tente novamente." }, "invalidVerificationCode": { "message": "Código de verificação inválido" @@ -6241,7 +6322,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Erro ao se conectar com o serviço Duo. Use um método de verificação de duas etapas diferente ou contate o Duo para assistência." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Inicie o Duo e siga os passos para finalizar o login." @@ -7745,7 +7826,7 @@ "message": "Já tem uma conta?" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Ativar/desativar navegação lateral" }, "skipToContent": { "message": "Pular para o conteúdo" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Atribuir a estas coleções" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8256,7 +8340,7 @@ "message": "Configurar ações do Github" }, "setUpKubernetes": { - "message": "Set up Kubernetes" + "message": "Configurar Kubernetes" }, "setUpGitlabCICD": { "message": "Configurar GitLab CI/CD" @@ -8265,7 +8349,7 @@ "message": "Configurar Ansible" }, "rustSDKRepo": { - "message": "View Rust repository" + "message": "Visualizar repositório Rust" }, "cSharpSDKRepo": { "message": "Visualizar repositório C#" @@ -8444,10 +8528,10 @@ "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." }, "upgradeOrganizationEnterprise": { - "message": "Identify security risks by auditing member access" + "message": "Identifique os riscos de segurança ao verificar o acesso de membros" }, "onlyAvailableForEnterpriseOrganization": { - "message": "Quickly view member access across the organization by upgrading to an Enterprise plan." + "message": "Visualize rapidamente o acesso de membros em toda a organização atualizando para um plano empresarial." }, "date": { "message": "Data" @@ -8456,28 +8540,28 @@ "message": "Exportar relatório do cliente" }, "memberAccessReport": { - "message": "Member access" + "message": "Acesso de membros" }, "memberAccessReportDesc": { - "message": "Ensure members have access to the right credentials and their accounts are secure. Use this report to obtain a CSV of member access and account configurations." + "message": "Garanta que membros tenham acesso às credenciais certas e que suas contas estejam seguras. Utilize este relatório para obter um CSV do acesso de membros e configurações de conta." }, "memberAccessReportPageDesc": { - "message": "Audit organization member access across groups, collections, and collection items. The CSV export provides a detailed breakdown per member, including information on collection permissions and account configurations." + "message": "Avalie o acesso de membros da organização entre grupos, coleções e itens de coleções. O exporte CSV fornece informações detalhadas por membro, incluindo informações sobre permissões de coleção e configurações de conta." }, "higherKDFIterations": { - "message": "Higher KDF iterations can help protect your master password from being brute forced by an attacker." + "message": "Iterações KDF mais altas podem ajudar a proteger sua senha mestra de ser descoberta por força bruta por alguém mal-intencionado." }, "incrementsOf100,000": { - "message": "increments of 100,000" + "message": "incrementos de 100.000" }, "smallIncrements": { - "message": "small increments" + "message": "pequenos incrementos" }, "kdfIterationRecommends": { - "message": "We recommend 600,000 or more" + "message": "Recomendamos 600.000 ou mais" }, "kdfToHighWarningIncreaseInIncrements": { - "message": "For older devices, setting your KDF too high may lead to performance issues. Increase the value in $VALUE$ and test your devices.", + "message": "Para dispositivos mais antigos, configurar seu KDF muito alto pode causar problemas de desempenho. Aumente o valor em $VALUE$ e teste seus dispositivos.", "placeholders": { "value": { "content": "$1", @@ -8486,31 +8570,31 @@ } }, "providerReinstate": { - "message": " Contact Customer Support to reinstate your subscription." + "message": " Contate o Atendimento ao Cliente para restabelecer sua assinatura." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Conceder acesso a este segredo a grupos ou pessoas. As permissões definidas para pessoas irão substituir as permissões definidas por grupos." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Adicione pessoas ou grupos para compartilhar o acesso a este segredo" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Conceda contas de máquinas acesso a este segredo." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Adicione contas de máquina para conceder acesso a este segredo" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Remover acesso a este segredo" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Esta ação removerá seu acesso a este segredo." }, "invoice": { - "message": "Invoice" + "message": "Fatura" }, "unassignedSeatsAvailable": { - "message": "You have $SEATS$ unassigned seats available.", + "message": "Você tem $SEATS$ vagas não atribuídas disponíveis.", "placeholders": { "seats": { "content": "$1", @@ -8520,21 +8604,21 @@ "description": "A message showing how many unassigned seats are available for a provider." }, "contactYourProviderForAdditionalSeats": { - "message": "Contact your provider admin to purchase additional seats." + "message": "Entre em contato com o administrador do seu provedor para comprar lugares adicionais." }, "open": { - "message": "Open", + "message": "Abrir", "description": "The status of an invoice." }, "uncollectible": { - "message": "Uncollectible", + "message": "Incolecionável", "description": "The status of an invoice." }, "clientDetails": { - "message": "Client details" + "message": "Detalhes de cliente" }, "downloadCSV": { - "message": "Download CSV" + "message": "Baixar CSV" }, "monthlySubscriptionUserSeatsMessage": { "message": "Adjustments to your subscription will result in prorated charges to your billing totals on your next billing period. " @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 9c6b41fbb81..d8b3b582461 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Itens movidos para $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item movido para $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Eliminar item" }, @@ -628,16 +646,16 @@ "message": "A sua sessão expirou." }, "restartRegistration": { - "message": "Restart registration" + "message": "Reiniciar registo" }, "expiredLink": { - "message": "Expired link" + "message": "Link expirado" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Por favor, reinicie o registo ou tente iniciar sessão." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "É possível que já tenha uma conta" }, "logOutConfirmation": { "message": "Tem a certeza de que pretende terminar sessão?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Erro ao desencriptar o ficheiro exportado. A sua chave de encriptação não corresponde à chave de encriptação utilizada para exportar os dados." }, - "importDestination": { - "message": "Destino da importação" + "destination": { + "message": "Destino" }, "learnAboutImportOptions": { "message": "Saiba mais sobre as suas opções de importação" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Controlo de acesso" }, - "groupAccessAllItems": { - "message": "Este grupo pode aceder e modificar todos os itens." - }, - "groupAccessSelectedCollections": { - "message": "Este grupo pode aceder apenas a coleções selecionadas." - }, "readOnly": { "message": "Só de leitura" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Este utilizador está a utilizar a verificação de dois passos para proteger a sua conta." }, - "userAccessAllItems": { - "message": "Este utilizador pode aceder e modificar todos os itens." - }, - "userAccessSelectedCollections": { - "message": "Este utilizador pode aceder apenas a coleções selecionadas." - }, "search": { "message": "Procurar" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Foi convidado a juntar-se à organização listada acima. Para aceitar o convite, é necessário iniciar sessão ou criar uma nova conta Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Conclua a adesão a esta organização ao definir uma palavra-passe mestra." + }, "inviteAccepted": { "message": "Convite aceite" }, @@ -4377,6 +4386,9 @@ "message": "Link do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copiar link" + }, "copySendLink": { "message": "Copiar link do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "ou", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "As equipas de desenvolvimento, DevOps e TI escolhem o Bitwarden - Gestor de Segredos para gerir e implementar de forma segura a sua infraestrutura e os segredos das máquinas." + }, + "centralizeSecretsManagement": { + "message": "Centralize a gestão de segredos." + }, + "centralizeSecretsManagementDescription": { + "message": "Armazene e gira segredos de forma segura num único local para evitar a dispersão de segredos pela sua organização." + }, + "preventSecretLeaks": { + "message": "Previna fugas de segredos." + }, + "preventSecretLeaksDescription": { + "message": "Proteja os segredos com encriptação ponto a ponto. Acabaram-se os segredos de código rígido ou a partilha através de ficheiros .env." + }, + "enhanceDeveloperProductivity": { + "message": "Melhore a produtividade dos programadores." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Recupere e implante segredos programaticamente em tempo de execução para que os programadores se possam concentrar no que é mais importante, como melhorar a qualidade do código." + }, + "strengthenBusinessSecurity": { + "message": "Reforce a segurança das empresas." + }, + "strengthenBusinessSecurityDescription": { + "message": "Mantenha um controlo rigoroso sobre o acesso de máquinas e pessoas a segredos com integrações SSO, registos de eventos e rotatividade de acessos." + }, + "tryItNow": { + "message": "Experimente agora" + }, + "sendRequest": { + "message": "Enviar pedido" + }, + "addANote": { + "message": "Adicionar uma nota" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden - Gestor de Segredos" + }, + "moreProductsFromBitwarden": { + "message": "Mais produtos do Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Pedir acesso ao Gestor de Segredos" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "É necessária a aprovação do seu administrador para experimentar o Gestor de Segredos." + }, + "smAccessRequestEmailSent": { + "message": "Pedido de acesso ao e-mail do gestor de segredos enviado aos administradores." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Olá,\n\nEstou a solicitar uma subscrição do Bitwarden - Gestor de Segredos para a nossa equipa. O vosso apoio seria muito importante!\n\nO Bitwarden - Gestor de Segredos é uma solução de gestão de segredos encriptados ponto a ponto para armazenar, partilhar e implementar de forma segura credenciais de máquinas como chaves API, palavras-passe de bases de dados e certificados de autenticação.\n\nO Gestor de Segredos ajudar-nos-á a:\n\n- Melhorar a segurança\n- Simplificar as operações\n- Prevenir fugas de segredos dispendiosas\n\nPara pedirem uma versão experimental gratuita para a nossa equipa, por favor, contactem o Bitwarden.\n\nObrigado pela vossa ajuda!" + }, + "giveMembersAccess": { + "message": "Dar acesso aos membros:" + }, + "viewAndSelectTheMembers": { + "message": "ver e selecionar os membros a quem pretende dar acesso ao Gestor de Segredos." + }, + "openYourOrganizations": { + "message": "Abra as suas organizações" + }, + "usingTheMenuSelect": { + "message": "Utilizando o menu, selecione" + }, + "toGrantAccessToSelectedMembers": { + "message": "para conceder acesso aos membros selecionados." + }, "sendVaultCardTryItNow": { "message": "experimente-o agora", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Atribuir a estas coleções" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Apenas os membros da organização com acesso a estas coleções poderão ver o item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Apenas os membros da organização com acesso a estas coleções poderão ver os itens." }, "selectCollectionsToAssign": { @@ -8253,7 +8337,7 @@ "message": "Utilize o SDK do Gestor de Segredos do Bitwarden nas seguintes linguagens de programação para criar as suas próprias aplicações." }, "setUpGithubActions": { - "message": "Configurar ações do Github" + "message": "Configurar ações do GitHub" }, "setUpKubernetes": { "message": "Configurar o Kubernetes" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Selecionar pasta" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ serão permanentemente transferidos para a organização selecionada. Estes itens deixarão de lhe pertencer.", + "personalItemTransferWarningSingular": { + "message": "1 será permanentemente transferido para a organização selecionada. Este item deixará de lhe pertencer." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ itens serão permanentemente transferidos para a organização selecionada. Estes itens deixarão de lhe pertencer.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ serão permanentemente transferidos para $ORG$. Deixará de ser proprietário destes itens.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 será permanentemente transferido para a $ORG$. Este item deixará de lhe pertencer.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ itens serão permanentemente transferidos para $ORG$. Estes itens deixarão de lhe pertencer.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Dados" + }, "purchasedSeatsRemoved": { "message": "lugares adquiridos removidos" } diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index aa8a0aa6178..1f197f5da89 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Ștergere articol" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Eroare la decriptarea fișierului exportat. Cheia dvs. de criptare nu corespunde cu cheia de criptare folosită pentru a exporta datele." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Controlul accesului" }, - "groupAccessAllItems": { - "message": "Acest grup poate accesa și modifica toate articolele." - }, - "groupAccessSelectedCollections": { - "message": "Acest grup poate accesa doar colecțiile selectate." - }, "readOnly": { "message": "Numai în citire" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Acest utilizator folosește conectarea în două etape pentru a-și proteja contul." }, - "userAccessAllItems": { - "message": "Acest utilizator poate accesa și modifica toate articolele." - }, - "userAccessSelectedCollections": { - "message": "Acest utilizator poate accesa doar colecțiile selectate." - }, "search": { "message": "Căutare" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Ați fost invitat să vă alăturați organizației listate mai sus. Pentru a accepta invitația, trebuie să vă conectați sau să creați un cont Bitwarden nou." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitație acceptată" }, @@ -4377,6 +4386,9 @@ "message": "Link Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copiere link Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "sau", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "încercați-l acum", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index a370b92d980..4964fe8991b 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -46,7 +46,7 @@ "message": "Данные для авторизации" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Ключ аутентификатора" }, "number": { "message": "Номер" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Элементы перемещены в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Элемент перемещен в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Удалить элемент" }, @@ -628,16 +646,16 @@ "message": "Истек срок действия вашей сессии." }, "restartRegistration": { - "message": "Restart registration" + "message": "Перезапустить регистрацию" }, "expiredLink": { - "message": "Expired link" + "message": "Истекшая ссылка" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Пожалуйста, перезапустите регистрацию или попробуйте авторизоваться." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Возможно, у вас уже есть аккаунт" }, "logOutConfirmation": { "message": "Вы действительно хотите выйти?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Ошибка при расшифровке экспортированного файла. Ваш ключ шифрования не совпадает с ключом шифрования, использованным при экспорте данных." }, - "importDestination": { - "message": "Цель импорта" + "destination": { + "message": "Назначение" }, "learnAboutImportOptions": { "message": "Узнайте о возможностях импорта" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Контроль доступа" }, - "groupAccessAllItems": { - "message": "Эта группа может иметь доступ и изменять все элементы." - }, - "groupAccessSelectedCollections": { - "message": "Эта группа может иметь доступ только к выбранным коллекциям." - }, "readOnly": { "message": "Только чтение" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Этот пользователь использует двухэтапную аутентификацию для защиты своего аккаунта." }, - "userAccessAllItems": { - "message": "Эта пользователь может иметь доступ и изменять все элементы." - }, - "userAccessSelectedCollections": { - "message": "Этот пользователь может иметь доступ только к выбранным коллекциям." - }, "search": { "message": "Поиск" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Вас пригласили присоединиться к организации, указанной выше. Чтобы принять приглашение, вам необходимо войти или создать новую учетную запись Bitwarden." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Завершите присоединение к этой организации, установив мастер-пароль." + }, "inviteAccepted": { "message": "Приглашение принято" }, @@ -3811,7 +3820,7 @@ "message": "Вы ничего не выбрали." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Получайте советы, анонсы и возможности для исследований от Bitwarden на свой email." }, "unsubscribe": { "message": "Отписаться" @@ -4377,6 +4386,9 @@ "message": "Ссылка на Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Скопировать ссылку" + }, "copySendLink": { "message": "Скопировать ссылку на Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "или", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Команды разработчиков, DevOps и ИТ-специалистов выбирают Bitwarden Secrets Manager для защищенного управления и развертывания своих инфраструктурных и машинных секретов." + }, + "centralizeSecretsManagement": { + "message": "Централизуйте управление секретами." + }, + "centralizeSecretsManagementDescription": { + "message": "Защищенное хранение и управление секретами в одном месте, чтобы предотвратить распространение секретов по всей организации." + }, + "preventSecretLeaks": { + "message": "Предотвратите утечку секретов." + }, + "preventSecretLeaksDescription": { + "message": "Защитите секреты с помощью сквозного шифрования. Больше не нужно кодировать секреты или делиться ими через файлы .env." + }, + "enhanceDeveloperProductivity": { + "message": "Повысьте производительность разработчиков." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Программное извлечение и развертывание секретов, чтобы разработчики могли сосредоточиться на том, что больше всего важнее, например, улучшение качества кода." + }, + "strengthenBusinessSecurity": { + "message": "Укрепление безопасности бизнеса." + }, + "strengthenBusinessSecurityDescription": { + "message": "Обеспечение жесткого контроля над доступом машин и людей к секретам с помощью интеграции SSO, журналов событий и ротации доступа." + }, + "tryItNow": { + "message": "Попробуйте сейчас" + }, + "sendRequest": { + "message": "Отправить запрос" + }, + "addANote": { + "message": "Добавить заметку" + }, + "bitwardenSecretsManager": { + "message": "Менеджер секретов Bitwarden" + }, + "moreProductsFromBitwarden": { + "message": "Другие продукты от Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Запросить доступ к менеджеру секретов" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "Чтобы попробовать Менеджер секретов, необходимо получить разрешение администратора." + }, + "smAccessRequestEmailSent": { + "message": "Запрос доступа к Менеджеру секретов отправлен администраторам по email." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Привет,\n\nЯ запрашиваю подписку на Менеджер секретов Bitwarden для нашей команды. Ваша поддержка будет иметь большое значение!\n\nМенеджер секретов Bitwarden — это комплексное решение для управления секретами с шифрованием, предназначенное для защищенного хранения, совместного использования и развертывания машинных учетных данных, таких как ключи API, пароли баз данных и сертификаты аутентификации.\n\nМенеджер секретов поможет нам:\n\n- улучшить защищенность\n- отимизировать операции\n- предотвратить дорогостоящие утечки секретной информации\n\nЧтобы запросить бесплатную пробную версию для нашей команды, обратитесь в Bitwarden.\n\nСпасибо за помощь!" + }, + "giveMembersAccess": { + "message": "Предоставить участникам доступ:" + }, + "viewAndSelectTheMembers": { + "message": "просмотрите и выберите участников, которым вы хотите предоставить доступ к Менеджеру секретов." + }, + "openYourOrganizations": { + "message": "Открыть вашу организацию" + }, + "usingTheMenuSelect": { + "message": "С помощью меню выберите" + }, + "toGrantAccessToSelectedMembers": { + "message": "чтобы предоставить доступ отмеченным пользователям." + }, "sendVaultCardTryItNow": { "message": "попробуйте прямо сейчас", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Назначить этим коллекциям" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Только члены организации, имеющие доступ к этим коллекциям, смогут видеть элементы." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Только члены организации, имеющие доступ к этим коллекциям, смогут видеть элементы." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Выбрать папку" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ будут навсегда переданы выбранной организации. Вы больше не будете владельцем этих элементов.", + "personalItemTransferWarningSingular": { + "message": "1 элемент будет навсегда передан выбранной организации. Вы больше не будете владельцем этих элементов." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ элементов будут навсегда переданы выбранной организации. Вы больше не будете владельцем этих элементов.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ будут навсегда переданы $ORG$. Вы больше не будете владельцем этих элементов.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 элемент будет навсегда передан $ORG$. Вы больше не будете владельцем этих элементов.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ элементов будут навсегда переданы $ORG$. Вы больше не будете владельцем этих элементов.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Данные" + }, "purchasedSeatsRemoved": { "message": "купленные места удалены" } diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index c4adb0521e5..2a5c89cb7a3 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 78750ade85d..e0cb3aab0e5 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Položky presunuté do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Položka presunutá do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Odstrániť položku" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Chyba pri dešifrovaní exportovaného súboru. Váš šifrovací kľúč sa nezhoduje so šifrovacím kľúčom použitým pri exporte údajov." }, - "importDestination": { - "message": "Cieľ importu" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Zistiť viac o možnostiach importu" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Riadenie prístupu" }, - "groupAccessAllItems": { - "message": "Táto skupina môže upravovať a pristupovať k všetkým položkám." - }, - "groupAccessSelectedCollections": { - "message": "Táto skupina môže upravovať a pristupovať len k položkám ktoré sú vo vybraných zbierkach." - }, "readOnly": { "message": "Iba na čítanie" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Tento používateľ používa dvojstupňové overovanie aby si zabezpečil konto." }, - "userAccessAllItems": { - "message": "Tento používateľ môže upravovať a pristupovať k všetkým položkám." - }, - "userAccessSelectedCollections": { - "message": "Tento používateľ môže upravovať a pristupovať len k položkám ktoré sú vo vybraných zbierkach." - }, "search": { "message": "Hľadať" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Obdržali ste pozvánku do vyššie menovanej Organizácie. Ak chcete pozvánku prijať, musíte sa prihlásiť alebo si vytvoriť nový Bitwarden účet." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Pozvánka prijatá" }, @@ -4377,6 +4386,9 @@ "message": "Odkaz na Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopírovať odkaz na Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "alebo", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "to skúste teraz", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Prideliť k týmto zbierkam" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Vybrať zložku" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ sa natrvalo prenesie do vybranej organizácie. Tieto položky už nebudete vlastniť.", + "personalItemTransferWarningSingular": { + "message": "Do vybranej organizácie sa položka natrvalo presunie. Už ju nebudete vlastniť." + }, + "personalItemsTransferWarningPlural": { + "message": "Do vybranej organizácie sa natrvalo presunú $PERSONAL_ITEMS_COUNT$ položky. Tieto položky už nebudete vlastniť.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ sa natrvalo prenesie do $ORG$. Tieto položky už nebudete vlastniť.", + "personalItemWithOrgTransferWarningSingular": { + "message": "Položka sa natrvalo presunie do $ORG$. Už ju nebudete vlastniť.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "Do $ORG$ sa natrvalo presunú $PERSONAL_ITEMS_COUNT$. Tieto položky už nebudete vlastniť.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "zakúpené sedenia boli odstránené" } diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index f476bb5b1a3..e817f8b1a19 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Izbriši element" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Dešifriranje izvožene datoteke je spodletelo. Ključ za dešifriranje se ne ujema s ključem, ki je bil uporabljen pri izvozu." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Iskanje" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Povezava pošiljke", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 038e9436f72..2293ac91806 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -43,10 +43,10 @@ "message": "Име власника картице" }, "loginCredentials": { - "message": "Login credentials" + "message": "Акредитиве за пријављивање" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Кључ аутентификатора" }, "number": { "message": "Број" @@ -145,13 +145,13 @@ "message": "Једнократни код" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Учините верификацију у 2 корака беспрекорном" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden може да чува и попуњава верификационе кодове у 2 корака. Копирајте и налепите кључ у ово поље." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden може да чува и попуњава верификационе кодове у 2 корака. Изаберите икону камере да бисте направили снимак екрана QR кода за аутентификацију ове веб локације или копирајте и налепите кључ у ово поље." }, "folder": { "message": "Фасцикла" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Ставке премештене у $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Ставка премештена у $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Обриши ставку" }, @@ -628,16 +646,16 @@ "message": "Ваша сесија је истекла." }, "restartRegistration": { - "message": "Restart registration" + "message": "Поново покрените регистрацију" }, "expiredLink": { - "message": "Expired link" + "message": "Истекла веза" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Поново покрените регистрацију или покушајте да се пријавите." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Можда већ имате налог" }, "logOutConfirmation": { "message": "Заиста желите да се одјавите?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Грешка у дешифрирању извозне датотеке. Ваш кључ за шифровање не одговара кључу који се користио за извоз података." }, - "importDestination": { - "message": "Смештај увоза" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Сазнајте више о опцијама увоза" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Контрола Приступа" }, - "groupAccessAllItems": { - "message": "Ова група може приступити и изменити све ставке." - }, - "groupAccessSelectedCollections": { - "message": "Ова група може приступити само одабраним колекцијама." - }, "readOnly": { "message": "Само за читање" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Овај корисник користи пријаву у два корака за заштиту свог налога." }, - "userAccessAllItems": { - "message": "Овај корисник може приступити и изменити све ставке." - }, - "userAccessSelectedCollections": { - "message": "Овај корисник може приступити само одабраним колекцијама." - }, "search": { "message": "Тражи" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Позвани сте да се придружите наведеној организацији. Да бисте прихватили позивницу, потребно је да се пријавите или направите нови Bitwarden налог." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Позив прихваћен" }, @@ -4377,6 +4386,9 @@ "message": "УРЛ „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Копирај УРЛ „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "или", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "пробај сада", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Додели овим колекцијама" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Изабери фасциклу" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ биће трајно пребачени у изабрану организацију. Више нећете имати ове ставке.", + "personalItemTransferWarningSingular": { + "message": "1 ставка биће трајно пребачена у изабрану организацију. Више нећете имати ову ставку." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ ставке биће трајно пребачени у изабрану организацију. Више нећете имати ове ставке.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ биће трајно пребачени у $ORG$. Више нећете имати ове ставке.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 ставка биће трајно пребачена у $ORG$. Више нећете имати ову ставку.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ ставке биће трајно пребачени у $ORG$. Више нећете имати ове ставке.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Подаци" + }, "purchasedSeatsRemoved": { "message": "купљена места уклоњена" } diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index 02269bb0340..a8af22d5d70 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Obriši stavku" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Kontrola Pristupa" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "ili", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index dceee53c585..ced709fb023 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -46,7 +46,7 @@ "message": "Login credentials" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Autentiseringsnyckel" }, "number": { "message": "Nummer" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Radera objekt" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Ett fel uppstod vid dekryptering av den exporterade filen. Din krypteringsnyckel matchar inte krypteringsnyckeln som användes för att exportera datan." }, - "importDestination": { - "message": "Importdestination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Läs mer om dina importalternativ" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Åtkomstkontroll" }, - "groupAccessAllItems": { - "message": "Denna grupp kan komma åt och ändra alla objekt." - }, - "groupAccessSelectedCollections": { - "message": "Denna grupp kan endast komma åt de markerade samlingarna." - }, "readOnly": { "message": "Skrivskyddad" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Denna användare använder tvåstegsverifiering för att skydda sitt konto." }, - "userAccessAllItems": { - "message": "Denna användare kan komma åt och ändra alla objekt." - }, - "userAccessSelectedCollections": { - "message": "Denna användare kan endast komma åt de markerade samlingarna." - }, "search": { "message": "Sök" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Du har bjudits in att gå med i organisationen ovan. För att acceptera inbjudan måste du logga in eller skapa ett nytt Bitwarden-konto." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Inbjudan accepterades" }, @@ -4377,6 +4386,9 @@ "message": "Send-länk", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopiera Send-länk", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "eller", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "prova det nu", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Välj mapp" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index 31a61b1185e..d5514bd6846 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index f73ca20ee85..42ca307c1fe 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Delete item" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Search" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4377,6 +4386,9 @@ "message": "Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "or", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "try it now", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index dfa5464d6bb..508fc83fd77 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -43,10 +43,10 @@ "message": "Kart sahibinin adı" }, "loginCredentials": { - "message": "Login credentials" + "message": "Hesap bilgileri" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Kimlik doğrulama anahtarı" }, "number": { "message": "Numara" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Kaydı sil" }, @@ -628,16 +646,16 @@ "message": "Oturumunuz zaman aşımına uğradı." }, "restartRegistration": { - "message": "Restart registration" + "message": "Kaydı yeniden başlat" }, "expiredLink": { - "message": "Expired link" + "message": "Bağlantının süresi dolmuş" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Lütfen kaydı yeniden başlatın veya giriş yapmayı deneyin." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Zaten hesabınız olabilir" }, "logOutConfirmation": { "message": "Çıkmak istediğinizden emin misiniz?" @@ -814,7 +832,7 @@ "message": "Ana parola ipucu" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Parolanızı unutursanız parola ipucunuzu e-posta adresinize gönderebiliriz. Maksimum $CURRENT$/$MAXIMUM$ karakter.", "placeholders": { "current": { "content": "$1", @@ -882,7 +900,7 @@ "message": "E-posta adresi" }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Kasanız kilitli" }, "uuid": { "message": "UUID" @@ -1009,17 +1027,17 @@ "message": "Kimlik doğrulama uygulaması" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Kimlik doğrulama uygulamanızın (örn. Bitwarden Authenticator) ürettiği kodu girin.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP security key" + "message": "YubiKey OTP güvenlik anahtarı" }, "yubiKeyDesc": { "message": "YubiKey 4, 5 veya NEO cihazı kullanın." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Duo Security'nin ürettiği kodu girin.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1045,7 +1063,7 @@ "message": "E-posta" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "E-posta adresinize gönderilen kodu girin." }, "continue": { "message": "Devam" @@ -1087,7 +1105,7 @@ "message": "Devam etmek istediğinizden emin misiniz?" }, "moveSelectedItemsDesc": { - "message": "Choose a folder that you would like to add the $COUNT$ selected item(s) to.", + "message": "Seçtiğiniz $COUNT$ kaydı eklemek istediğiniz klasörü seçin.", "placeholders": { "count": { "content": "$1", @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Dışa aktarılmış dosya çözülemedi. Şifreleme anahtarınız, veri dışa aktarılırken kullanılanla uyuşmuyor." }, - "importDestination": { - "message": "İçe aktarma hedefi" + "destination": { + "message": "Hedef" }, "learnAboutImportOptions": { "message": "İçe aktarma seçeneklerinizi öğrenin" @@ -1698,7 +1716,7 @@ "message": "." }, "continueToExternalUrlTitle": { - "message": "Continue to $URL$?", + "message": "%1$s adresine gidilsin mi?", "placeholders": { "url": { "content": "$1", @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Erişim kontrolü" }, - "groupAccessAllItems": { - "message": "Bu grup tüm kayıtlara erişebilir ve onları değiştirebilir." - }, - "groupAccessSelectedCollections": { - "message": "Bu grup sadece seçili koleksiyonlara erişebilir." - }, "readOnly": { "message": "Salt okunur" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Bu kullanıcı hesabını korumak için iki aşamalı giriş kullanıyor." }, - "userAccessAllItems": { - "message": "Bu kullanıcı tüm kayıtlara erişebilir ve onları değiştirebilir." - }, - "userAccessSelectedCollections": { - "message": "Bu kullanıcı sadece seçili koleksiyonlara erişebilir." - }, "search": { "message": "Ara" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Yukarıdaki kuruluşa katılmaya davet edildiniz. Daveti kabul etmek için giriş yapmanız veya yeni bir Bitwarden hesabı açmanız gerekiyor." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Kuruluşa katılmayı tamamlamak için ana parolanızı belirleyin." + }, "inviteAccepted": { "message": "Davet kabul edildi" }, @@ -3811,7 +3820,7 @@ "message": "Hiçbir şey seçmediniz." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Bitwarden'dan öneriler, duyurular ve araştırma fırsatları e-posta adresinize gelsin." }, "unsubscribe": { "message": "İstediğiniz zaman" @@ -4377,6 +4386,9 @@ "message": "Send bağlantısı", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Bağlantıyı kopyala" + }, "copySendLink": { "message": "Send bağlantısını kopyala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "veya", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "hemen deneyin", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -6103,7 +6184,7 @@ "message": "Cihaz doğrulaması güncellendi" }, "areYouSureYouWantToEnableDeviceVerificationTheVerificationCodeEmailsWillArriveAtX": { - "message": "Cihaz Doğrulamayı etkinleştirmek istediğinizden emin misiniz? Doğrulama kodu e-postaları şu adrese gelecek: $EMAIL$", + "message": "Cihaz doğrulamayı açmak istediğinizden emin misiniz? Doğrulama kodu e-postaları $EMAIL$ adresine gönderilecektir", "placeholders": { "email": { "content": "$1", @@ -7232,7 +7313,7 @@ "description": "Software Development Kit" }, "createAnAccount": { - "message": "Bir hesap oluşturun" + "message": "Hesap oluştur" }, "createSecret": { "message": "Sır oluştur" @@ -7886,7 +7967,7 @@ "message": "1 yıl boyunca ücretsiz" }, "newWebApp": { - "message": "Yeni ve geliştirilmiş web uygulamasına hoş geldiniz. Nelerin değiştiği hakkında daha fazla bilgi edinin." + "message": "Yeni ve geliştirilmiş web uygulamasına hoş geldiniz. Nelerin değiştiğini öğrenin." }, "releaseBlog": { "message": "Sürüm blogunu okuyun" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Bu koleksiyonlara ata" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Klasör seç" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Veri" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index cd91889b200..b6cd1f87616 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -43,10 +43,10 @@ "message": "Ім'я власника картки" }, "loginCredentials": { - "message": "Login credentials" + "message": "Облікові дані для входу" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Ключ автентифікації" }, "number": { "message": "Номер" @@ -145,13 +145,13 @@ "message": "Ключ автентифікації (TOTP)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Спростіть двоетапну перевірку" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden може автоматично заповнювати одноразові коди двоетапної перевірки. Скопіюйте і вставте ключ у це поле." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden може автоматично заповнювати одноразові коди двоетапної перевірки. Відкрийте камеру, щоб сканувати QR-код на цьому вебсайті, або скопіюйте і вставте ключ у це поле." }, "folder": { "message": "Тека" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Видалити запис" }, @@ -628,16 +646,16 @@ "message": "Тривалість вашого сеансу завершилась." }, "restartRegistration": { - "message": "Restart registration" + "message": "Перезапустити реєстрацію" }, "expiredLink": { - "message": "Expired link" + "message": "Протерміноване посилання" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Перезапустіть реєстрацію або спробуйте ввійти." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Можливо, ви вже зареєстровані" }, "logOutConfirmation": { "message": "Ви дійсно хочете вийти?" @@ -882,7 +900,7 @@ "message": "Адреса е-пошти" }, "yourVaultIsLockedV2": { - "message": "Ваше сховище заблоковано." + "message": "Ваше сховище заблоковано" }, "uuid": { "message": "UUID" @@ -1087,7 +1105,7 @@ "message": "Ви дійсно хочете продовжити?" }, "moveSelectedItemsDesc": { - "message": "Choose a folder that you would like to add the $COUNT$ selected item(s) to.", + "message": "Оберіть теку, в яку ви бажаєте додати $COUNT$ вибраних записів.", "placeholders": { "count": { "content": "$1", @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "Помилка розшифрування експортованого файлу. Ваш ключ шифрування відрізняється від ключа, використаного для експортування даних." }, - "importDestination": { - "message": "Призначення імпорту" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Дізнайтеся про параметри імпорту" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Контроль доступу" }, - "groupAccessAllItems": { - "message": "Ця грума має доступ і дозвіл редагування записів." - }, - "groupAccessSelectedCollections": { - "message": "Ця група має доступ лише до окремих збірок." - }, "readOnly": { "message": "Лише читання" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "Цей користувач використовує двоетапну перевірку для захисту свого облікового запису." }, - "userAccessAllItems": { - "message": "Цей користувач має доступ і можливість змінювати всі записи." - }, - "userAccessSelectedCollections": { - "message": "Цей користувач має доступ лише до обраних збірок." - }, "search": { "message": "Пошук" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "Вас було запрошено приєднатися до зазначеної вгорі організації. Щоб підтвердити запрошення, вам необхідно увійти в обліковий запис Bitwarden, або створити його." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Запрошення прийнято" }, @@ -3811,7 +3820,7 @@ "message": "Ви нічого не обрали." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Отримуйте поради, оголошення та можливості дослідження від Bitwarden у своїй поштовій скриньці." }, "unsubscribe": { "message": "Відписатися" @@ -4377,6 +4386,9 @@ "message": "Посилання на відправлення", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Копіювати посилання відправлення", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "або", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "спробуйте", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -5547,7 +5628,7 @@ "message": "Потрібний код підтвердження." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Автентифікацію було скасовано або вона тривала надто довго. Повторіть спробу." }, "invalidVerificationCode": { "message": "Недійсний код підтвердження" @@ -6241,7 +6322,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Помилка під'єднання до служби Duo. Скористайтеся іншим способом двоетапної перевірки або зверніться до служби підтримки Duo по допомогу." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Запустіть Duo і виконайте дії для завершення входу." @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Призначити до цих збірок" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8562,29 +8646,41 @@ "message": "Спонсоровано" }, "licenseAndBillingManagementDesc": { - "message": "After making updates in the Bitwarden cloud server, upload your license file to apply the most recent changes." + "message": "Після оновлень на сервері Bitwarden вивантажте свій файл ліцензії, щоб застосувати останні зміни." }, "addToFolder": { - "message": "Add to folder" + "message": "Додати теку" }, "selectFolder": { - "message": "Select folder" + "message": "Вибрати теку" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,7 +8688,10 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { - "message": "purchased seats removed" + "message": "куплених місць вилучено" } } diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index a2b11db55b4..0330ca5d56e 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -43,10 +43,10 @@ "message": "Tên chủ thẻ" }, "loginCredentials": { - "message": "Login credentials" + "message": "Thông tin đăng nhập" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Khóa xác thực" }, "number": { "message": "Số" @@ -61,7 +61,7 @@ "message": "Mã bảo mật (CVV)" }, "identityName": { - "message": "Tên định danh" + "message": "Tên danh tính" }, "company": { "message": "Công ty" @@ -189,7 +189,7 @@ "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { - "message": "You", + "message": "Bạn", "description": "Used as a label to indicate that the user is the owner of an item." }, "addFolder": { @@ -298,7 +298,7 @@ "description": "Search Card type" }, "searchIdentity": { - "message": "Tìm kiếm danh bạ", + "message": "Tìm kiếm danh tính", "description": "Search Identity type" }, "searchSecureNote": { @@ -336,7 +336,7 @@ "message": "Thẻ" }, "typeIdentity": { - "message": "Danh bạ" + "message": "Danh tính" }, "typeSecureNote": { "message": "Ghi chú" @@ -348,7 +348,7 @@ "message": "Thẻ" }, "typeIdentityPlural": { - "message": "Danh bạ" + "message": "Danh tính" }, "typeSecureNotePlural": { "message": "Ghi chú" @@ -421,10 +421,10 @@ "message": "Mục" }, "itemDetails": { - "message": "Item details" + "message": "Chi tiết mục" }, "itemName": { - "message": "Item name" + "message": "Tên mục" }, "cannotRemoveViewOnlyCollections": { "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "Xóa mục" }, @@ -667,7 +685,7 @@ "message": "Đăng nhập bằng mật khẩu chính" }, "readingPasskeyLoading": { - "message": "Đang đọc passkey..." + "message": "Đang đọc mã khoá..." }, "readingPasskeyLoadingInfo": { "message": "Giữ cửa sổ này mở và làm theo lời nhắc từ trình duyệt của bạn." @@ -676,40 +694,40 @@ "message": "Dùng phương thức đăng nhập khác" }, "loginWithPasskey": { - "message": "Log in with passkey" + "message": "Đăng nhập bằng mã khoá" }, "invalidPasskeyPleaseTryAgain": { - "message": "PassKey sai. Hãy thử lại." + "message": "Mã khoá không hợp lệ. Vui lòng thử lại." }, "twoFactorForPasskeysNotSupportedOnClientUpdateToLogIn": { - "message": "Chưa hỗ trợ 2FA cho PassKey. Cập nhật app để đăng nhập." + "message": "Chưa hỗ trợ 2FA cho mã khoá. Cập nhật ứng dụng để đăng nhập." }, "loginWithPasskeyInfo": { "message": "Use a generated passkey that will automatically log you in without a password. Biometrics, like facial recognition or fingerprint, or another FIDO2 security method will verify your identity." }, "newPasskey": { - "message": "New passkey" + "message": "Mã khoá mới" }, "learnMoreAboutPasswordless": { "message": "Learn more about passwordless" }, "creatingPasskeyLoading": { - "message": "Creating passkey..." + "message": "Đang tạo mã khoá..." }, "creatingPasskeyLoadingInfo": { "message": "Keep this window open and follow prompts from your browser." }, "errorCreatingPasskey": { - "message": "Error creating passkey" + "message": "Lỗi tạo mã khoá" }, "errorCreatingPasskeyInfo": { - "message": "There was a problem creating your passkey." + "message": "Xảy ra lỗi khi đang tạo mã khoá của bạn." }, "passkeySuccessfullyCreated": { - "message": "Passkey successfully created!" + "message": "Tạo mã khoá thành công!" }, "customPasskeyNameInfo": { - "message": "Name your passkey to help you identify it." + "message": "Đặt tên cho mã khoá của bạn để dễ phân biệt." }, "useForVaultEncryption": { "message": "Use for vault encryption" @@ -718,7 +736,7 @@ "message": "Log in and unlock on supported devices without your master password. Follow the prompts from your browser to finalize setup." }, "useForVaultEncryptionErrorReadingPasskey": { - "message": "Error reading passkey. Try again or uncheck this option." + "message": "Lỗi đọc mã khoá. Hãy thử lại hoặc bỏ tuỳ chọn này." }, "encryptionNotSupported": { "message": "Encryption not supported" @@ -730,10 +748,10 @@ "message": "Used for encryption" }, "loginWithPasskeyEnabled": { - "message": "Log in with passkey turned on" + "message": "Đăng nhập bằng mã khoá đã bật" }, "passkeySaved": { - "message": "$NAME$ saved", + "message": "$NAME$ đã lưu", "placeholders": { "name": { "content": "$1", @@ -742,28 +760,28 @@ } }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Đã xóa mã khoá" }, "removePasskey": { - "message": "Remove passkey" + "message": "Xóa mã khoá" }, "removePasskeyInfo": { - "message": "If all passkeys are removed, you will be unable to log into new devices without your master password." + "message": "Khi tất cả các mã khoá bị xóa, bạn phải sử dụng mật khẩu chính để đăng nhập vào thiết bị mới." }, "passkeyLimitReachedInfo": { - "message": "Passkey limit reached. Remove a passkey to add another." + "message": "Đã đạt giới hạn số lượng mã khoá. Xóa một mã khoá để thêm mã khoá khác." }, "tryAgain": { - "message": "Try again" + "message": "Thử lại" }, "createAccount": { "message": "Tạo tài khoản" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Đặt mật khẩu mạnh" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Hoàn thành việc tạo tài khoản của bạn bằng cách đặt mật khẩu" }, "newAroundHere": { "message": "Bạn mới dùng?" @@ -775,7 +793,7 @@ "message": "Đăng nhập" }, "verifyIdentity": { - "message": "Verify your Identity" + "message": "Xác minh danh tính của bạn" }, "logInInitiated": { "message": "Log in initiated" @@ -882,7 +900,7 @@ "message": "Địa chỉ email" }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Kho của bạn đã khóa" }, "uuid": { "message": "UUID" @@ -1009,17 +1027,17 @@ "message": "Ứng dụng xác thực" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Nhập mã được tạo bởi ứng dụng xác thực như Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP security key" + "message": "Khóa bảo mật OTP Yubico" }, "yubiKeyDesc": { "message": "Sử dụng YubiKey để truy cập tài khoản của bạn. Hoạt động với YubiKey 4, 5 và các thiết bị NEO." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Nhập mã được tạo bởi Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1033,7 +1051,7 @@ "message": "Mật khẩu FIDO U2F" }, "webAuthnTitle": { - "message": "Passkey" + "message": "Mã khoá" }, "webAuthnDesc": { "message": "Sử dụng bất kỳ khóa bảo mật tương thích với WebAuthn nào để truy cập vào tài khoản của bạn." @@ -1209,7 +1227,7 @@ "message": "Đã xuất dữ liệu kho của bạn" }, "passwordGenerator": { - "message": "Tạo mật khẩu" + "message": "Trình tạo mật khẩu" }, "minComplexityScore": { "message": "Độ phức tạp tối thiểu" @@ -1480,16 +1498,16 @@ } }, "importFormatError": { - "message": "Dữ liệu không được định dạng đúng cách, vui lòng kiểm tra và thử lại." + "message": "Dữ liệu không được định dạng đúng. Vui lòng kiểm tra tập tin nhập và thử lại." }, "importNothingError": { - "message": "Chưa nhập gì." + "message": "Không có gì được nhập." }, "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -2160,7 +2178,7 @@ "message": "Password hygiene, account health, and data breach reports to keep your vault safe." }, "premiumSignUpTotp": { - "message": "TOTP verification code (2FA) generator for logins in your vault." + "message": "Mã xác nhận TOTP (2FA) để đăng nhập vào kho của bạn." }, "premiumSignUpSupport": { "message": "Priority customer support." @@ -2781,12 +2799,6 @@ "accessControl": { "message": "Access control" }, - "groupAccessAllItems": { - "message": "This group can access and modify all items." - }, - "groupAccessSelectedCollections": { - "message": "This group can access only the selected collections." - }, "readOnly": { "message": "Read only" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, - "userAccessAllItems": { - "message": "This user can access and modify all items." - }, - "userAccessSelectedCollections": { - "message": "This user can access only the selected collections." - }, "search": { "message": "Tìm kiếm" }, @@ -3373,10 +3379,10 @@ "message": "User(s) invited" }, "resendInvitation": { - "message": "Resend invitation" + "message": "Gửi lại lời mời" }, "resendEmail": { - "message": "Resend email" + "message": "Gửi lại email" }, "hasBeenReinvited": { "message": "$USER$ reinvited", @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, @@ -4043,7 +4052,7 @@ "message": "Set requirements for password generator." }, "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." + "message": "Các chính sách của tổ chức đang ảnh hưởng đến cài đặt tạo mật khẩu của bạn." }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" @@ -4357,7 +4366,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "currentAccessCount": { - "message": "Số lượng truy cập hiện tại" + "message": "Số lần truy cập hiện tại" }, "sendPasswordDesc": { "message": "Optionally require a password for users to access this Send.", @@ -4374,9 +4383,12 @@ "message": "Revoked" }, "sendLink": { - "message": "Gửi liên kết", + "message": "Liên kết Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Sao chép liên kết mục Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "hoặc", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "thử ngay", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -5882,7 +5963,7 @@ "message": "Cài đặt tài khoản" }, "generator": { - "message": "Generator" + "message": "Trình tạo" }, "whatWouldYouLikeToGenerate": { "message": "What would you like to generate?" @@ -5900,7 +5981,7 @@ "message": "Username type" }, "plusAddressedEmail": { - "message": "Plus addressed email", + "message": "Địa chỉ email có hậu tố", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { @@ -7736,34 +7817,34 @@ "message": "Edited collections" }, "baseUrl": { - "message": "Server URL" + "message": "Địa chỉ máy chủ" }, "aliasDomain": { - "message": "Alias domain" + "message": "Tên miền thay thế" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "Bạn đã có tài khoản?" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Ẩn/hiện thanh điều hướng bên" }, "skipToContent": { - "message": "Vào nội dung chính" + "message": "Chuyển đến nội dung" }, "managePermissionRequired": { "message": "At least one member or group must have can manage permission." }, "typePasskey": { - "message": "Passkey" + "message": "Mã khoá" }, "passkeyNotCopied": { - "message": "Passkey will not be copied" + "message": "Không thể sao chép mã khoá" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "Bản sao sẽ không bao gồm mã khoá. Bạn có muốn tiếp tục tạo bản sao mục này?" }, "modifiedCollectionManagement": { - "message": "Cài đặt quản lý bộ sưu tập đã sửa đổi $ID$.", + "message": "Đã sửa đổi cài đặt quản lý bộ sưu tập $ID$.", "placeholders": { "id": { "content": "$1", @@ -7788,13 +7869,13 @@ "message": "Đã xảy ra lỗi khi tải mục Gửi này. Hãy thử lại sau." }, "seatLimitReached": { - "message": "Số ghế sử dụng hàng tháng đã đạt đến giới hạn" + "message": "Đã đạt giới hạn số lượng người dùng" }, "contactYourProvider": { - "message": "Liên hệ nhà cung cấp của bạn để mua thêm ghế." + "message": "Liên hệ nhà cung cấp của bạn để mua thêm suất." }, "seatLimitReachedContactYourProvider": { - "message": "Số ghế sử dụng hàng tháng đã đạt đến giới hạn. Liên hệ nhà cung cấp để mua thêm." + "message": "Đã đạt đến giới hạn số lượng người dùng. Liên hệ nhà cung cấp của bạn để mua thêm suất." }, "collectionAccessRestricted": { "message": "Collection access is restricted" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8520,10 +8604,10 @@ "description": "A message showing how many unassigned seats are available for a provider." }, "contactYourProviderForAdditionalSeats": { - "message": "Contact your provider admin to purchase additional seats." + "message": "Liên hệ nhà cung cấp của bạn để mua thêm suất." }, "open": { - "message": "Open", + "message": "Mở", "description": "The status of an invoice." }, "uncollectible": { @@ -8555,36 +8639,48 @@ "description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions, please contact Bitwarden support'." }, "contactBitwardenSupport": { - "message": "contact Bitwarden support.", + "message": "liên hệ với bộ phận hỗ trợ Bitwarden.", "description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions, please contact Bitwarden support'. 'Bitwarden' should not be translated" }, "sponsored": { - "message": "Sponsored" + "message": "Được tài trợ" }, "licenseAndBillingManagementDesc": { "message": "After making updates in the Bitwarden cloud server, upload your license file to apply the most recent changes." }, "addToFolder": { - "message": "Add to folder" + "message": "Thêm vào thư mục" }, "selectFolder": { - "message": "Select folder" + "message": "Chọn thư mục" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Dữ liệu" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 4c646b8e7f4..b248fb576b4 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -43,10 +43,10 @@ "message": "持卡人姓名" }, "loginCredentials": { - "message": "Login credentials" + "message": "登录凭据" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "验证器密钥" }, "number": { "message": "号码" @@ -145,13 +145,13 @@ "message": "验证器密钥 (TOTP)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "无缝两步验证" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden 可以存储并填充两步验证码。复制并粘贴密钥到此字段。" }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden 可以存储并填充两步验证码。选择相机图标来截取此网站的验证器二维码,或者手动复制并粘贴密钥到此字段。" }, "folder": { "message": "文件夹" @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "项目已移动到 $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "项目已移动到 $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "删除项目" }, @@ -628,16 +646,16 @@ "message": "您的登录会话已过期。" }, "restartRegistration": { - "message": "Restart registration" + "message": "重新开始注册" }, "expiredLink": { - "message": "Expired link" + "message": "失效链接" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "请重新注册或尝试登录。" }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "您可能已经有一个账户了" }, "logOutConfirmation": { "message": "确定要注销吗?" @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "解密导出的文件时出错。您的加密密钥与导出数据时使用的加密密钥不匹配。" }, - "importDestination": { - "message": "导入目的地" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "了解您的导入选项" @@ -2749,7 +2767,7 @@ "message": "确定要删除此群组吗?" }, "deleteMultipleGroupsConfirmation": { - "message": "确定要删除如下 $QUANTITY$ 个群组吗?", + "message": "确定要删除以下 $QUANTITY$ 个群组吗?", "placeholders": { "quantity": { "content": "$1", @@ -2781,12 +2799,6 @@ "accessControl": { "message": "访问控制" }, - "groupAccessAllItems": { - "message": "此群组可以访问和修改所有项目。" - }, - "groupAccessSelectedCollections": { - "message": "此群组只能访问选定的集合。" - }, "readOnly": { "message": "只读" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "此用户正在使用两步登录来保护他们的账户。" }, - "userAccessAllItems": { - "message": "此用户可以访问和修改所有项目。" - }, - "userAccessSelectedCollections": { - "message": "此用户只能访问选定的集合。" - }, "search": { "message": "搜索" }, @@ -3328,7 +3334,7 @@ "message": "设备" }, "creatingAccountOn": { - "message": "创建账户于" + "message": "正创建账户于" }, "checkYourEmail": { "message": "检查您的电子邮箱" @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "您已被邀请加入上面的组织。要接受邀请,您需要登录或者创建一个 Bitwarden 账户。" }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "通过设置主密码完成加入此组织。" + }, "inviteAccepted": { "message": "邀请已接受" }, @@ -3811,7 +3820,7 @@ "message": "您尚未选择任何内容。" }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "获取来自 Bitwarden 的建议、公告和调研电子邮件。" }, "unsubscribe": { "message": "取消订阅" @@ -4377,6 +4386,9 @@ "message": "Send 链接", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "复制 Send 链接", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "或", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "开发 DevOps 和 IT 团队选择 Bitwarden 机密管理器来安全管理和部署他们的基础设施和机器秘密。" + }, + "centralizeSecretsManagement": { + "message": "集中管理秘密。" + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "立即体验", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -4927,7 +5008,7 @@ "message": "此用户" }, "resetPasswordMasterPasswordPolicyInEffect": { - "message": "一个或多个组织策略要求主密码满足下列要求:" + "message": "一个或多个组织策略要求主密码满足以下要求:" }, "resetPasswordSuccess": { "message": "密码重置成功!" @@ -5032,7 +5113,7 @@ "message": "成功恢复组织的访问权限" }, "bulkFilteredMessage": { - "message": "已排除,不适用于此操作" + "message": "已拒绝,不适用于此操作" }, "fingerprint": { "message": "指纹" @@ -7366,7 +7447,7 @@ "description": "The individual description shown to the user when the user doesn't have access to delete a project." }, "smProjectsDeleteBulkConfirmation": { - "message": "无法删除下列工程。是否继续?", + "message": "以下工程无法删除。是否继续?", "description": "The message shown to the user when bulk deleting projects and the user doesn't have access to some projects." }, "updateKdfSettings": { @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "分配到这些集合" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "只有具有这些集合访问权限的组织成员才能看到这个项目。" + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "只有具有这些集合访问权限的组织成员才能看到这些项目。" }, "selectCollectionsToAssign": { @@ -7956,7 +8040,7 @@ "message": "剩余" }, "unlinkOrganization": { - "message": "取消链接组织" + "message": "脱离组织" }, "manageSeats": { "message": "管理席位" @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "选择文件夹" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ 将永久转移到所选组织。您将不再拥有这些项目。", + "personalItemTransferWarningSingular": { + "message": "1 个项目将永久转移到所选组织。您将不再拥有该项目。" + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 个项目将永久转移到所选组织。您将不再拥有这些项目。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ 将永久转移到 $ORG$。您将不再拥有这些项目。", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 个项目将永久转移到 $ORG$ 。您将不再拥有该项目。", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 个项目将永久转移到 $ORG$ 。您将不再拥有这些项目。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "购买的席位已移除" } diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index c59c5d77a6b..2b796167696 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -570,6 +570,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "deleteItem": { "message": "刪除項目" }, @@ -1488,8 +1506,8 @@ "importEncKeyError": { "message": "解密匯出的檔案時發生錯誤,您的加密金鑰與匯出資料時使用的金鑰不同。" }, - "importDestination": { - "message": "匯入目的地" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "瞭解更多匯入選項" @@ -2781,12 +2799,6 @@ "accessControl": { "message": "存取控制" }, - "groupAccessAllItems": { - "message": "此群組可存取及變更所有項目。" - }, - "groupAccessSelectedCollections": { - "message": "此群組只能存取選擇的集合。" - }, "readOnly": { "message": "唯讀" }, @@ -2832,12 +2844,6 @@ "userUsingTwoStep": { "message": "此使用者正在使用兩步驟登入保護帳戶。" }, - "userAccessAllItems": { - "message": "此使用者可存取及變更所有項目。" - }, - "userAccessSelectedCollections": { - "message": "此使用者只能存取選擇的集合。" - }, "search": { "message": "搜尋" }, @@ -3453,6 +3459,9 @@ "joinOrganizationDesc": { "message": "您已被邀請加入以上組織。若想接受邀請,您需要登入或建立新的 Bitwarden 帳戶。" }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "邀請已接受" }, @@ -4377,6 +4386,9 @@ "message": "Send 連結", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "複製 Send 連結", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -4792,6 +4804,75 @@ "message": "或", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, + "developmentDevOpsAndITTeamsChooseBWSecret": { + "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + }, + "centralizeSecretsManagement": { + "message": "Centralize secrets management." + }, + "centralizeSecretsManagementDescription": { + "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + }, + "preventSecretLeaks": { + "message": "Prevent secret leaks." + }, + "preventSecretLeaksDescription": { + "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + }, + "enhanceDeveloperProductivity": { + "message": "Enhance developer productivity." + }, + "enhanceDeveloperProductivityDescription": { + "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + }, + "strengthenBusinessSecurity": { + "message": "Strengthen business security." + }, + "strengthenBusinessSecurityDescription": { + "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + }, + "tryItNow": { + "message": "Try it now" + }, + "sendRequest": { + "message": "Send request" + }, + "addANote": { + "message": "Add a note" + }, + "bitwardenSecretsManager": { + "message": "Bitwarden Secrets Manager" + }, + "moreProductsFromBitwarden": { + "message": "More products from Bitwarden" + }, + "requestAccessToSecretsManager": { + "message": "Request access to Secrets Manager" + }, + "youNeedApprovalFromYourAdminToTrySecretsManager": { + "message": "You need approval from your administrator to try Secrets Manager." + }, + "smAccessRequestEmailSent": { + "message": "Access request for secrets manager email sent to admins." + }, + "requestAccessSMDefaultEmailContent": { + "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + }, + "giveMembersAccess": { + "message": "Give members access:" + }, + "viewAndSelectTheMembers": { + "message": "view and select the members you want to give access to Secrets Manager." + }, + "openYourOrganizations": { + "message": "Open your organization's" + }, + "usingTheMenuSelect": { + "message": "Using the menu, select" + }, + "toGrantAccessToSelectedMembers": { + "message": "to grant access to selected members." + }, "sendVaultCardTryItNow": { "message": "立即嘗試", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, or **try it now**.'" @@ -7915,7 +7996,10 @@ "assignToTheseCollections": { "message": "Assign to these collections" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "selectCollectionsToAssign": { @@ -8570,21 +8654,33 @@ "selectFolder": { "message": "Select folder" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -8592,6 +8688,9 @@ } } }, + "data": { + "message": "Data" + }, "purchasedSeatsRemoved": { "message": "purchased seats removed" } From 2fa69e337a1b51869e645cf16ccf94e34bd70ca5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:41:50 +0000 Subject: [PATCH 10/46] Autosync the updated translations (#10281) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/af/messages.json | 32 +- apps/desktop/src/locales/ar/messages.json | 32 +- apps/desktop/src/locales/az/messages.json | 32 +- apps/desktop/src/locales/be/messages.json | 32 +- apps/desktop/src/locales/bg/messages.json | 32 +- apps/desktop/src/locales/bn/messages.json | 32 +- apps/desktop/src/locales/bs/messages.json | 32 +- apps/desktop/src/locales/ca/messages.json | 32 +- apps/desktop/src/locales/cs/messages.json | 32 +- apps/desktop/src/locales/cy/messages.json | 32 +- apps/desktop/src/locales/da/messages.json | 32 +- apps/desktop/src/locales/de/messages.json | 32 +- apps/desktop/src/locales/el/messages.json | 78 ++- apps/desktop/src/locales/en_GB/messages.json | 32 +- apps/desktop/src/locales/en_IN/messages.json | 32 +- apps/desktop/src/locales/eo/messages.json | 32 +- apps/desktop/src/locales/es/messages.json | 32 +- apps/desktop/src/locales/et/messages.json | 32 +- apps/desktop/src/locales/eu/messages.json | 32 +- apps/desktop/src/locales/fa/messages.json | 32 +- apps/desktop/src/locales/fi/messages.json | 38 +- apps/desktop/src/locales/fil/messages.json | 32 +- apps/desktop/src/locales/fr/messages.json | 32 +- apps/desktop/src/locales/gl/messages.json | 32 +- apps/desktop/src/locales/he/messages.json | 32 +- apps/desktop/src/locales/hi/messages.json | 32 +- apps/desktop/src/locales/hr/messages.json | 32 +- apps/desktop/src/locales/hu/messages.json | 32 +- apps/desktop/src/locales/id/messages.json | 32 +- apps/desktop/src/locales/it/messages.json | 32 +- apps/desktop/src/locales/ja/messages.json | 32 +- apps/desktop/src/locales/ka/messages.json | 32 +- apps/desktop/src/locales/km/messages.json | 32 +- apps/desktop/src/locales/kn/messages.json | 32 +- apps/desktop/src/locales/ko/messages.json | 32 +- apps/desktop/src/locales/lt/messages.json | 32 +- apps/desktop/src/locales/lv/messages.json | 32 +- apps/desktop/src/locales/me/messages.json | 32 +- apps/desktop/src/locales/ml/messages.json | 32 +- apps/desktop/src/locales/mr/messages.json | 32 +- apps/desktop/src/locales/my/messages.json | 32 +- apps/desktop/src/locales/nb/messages.json | 32 +- apps/desktop/src/locales/ne/messages.json | 32 +- apps/desktop/src/locales/nl/messages.json | 32 +- apps/desktop/src/locales/nn/messages.json | 32 +- apps/desktop/src/locales/or/messages.json | 32 +- apps/desktop/src/locales/pl/messages.json | 32 +- apps/desktop/src/locales/pt_BR/messages.json | 32 +- apps/desktop/src/locales/pt_PT/messages.json | 36 +- apps/desktop/src/locales/ro/messages.json | 32 +- apps/desktop/src/locales/ru/messages.json | 32 +- apps/desktop/src/locales/si/messages.json | 32 +- apps/desktop/src/locales/sk/messages.json | 32 +- apps/desktop/src/locales/sl/messages.json | 32 +- apps/desktop/src/locales/sr/messages.json | 32 +- apps/desktop/src/locales/sv/messages.json | 32 +- apps/desktop/src/locales/te/messages.json | 32 +- apps/desktop/src/locales/th/messages.json | 32 +- apps/desktop/src/locales/tr/messages.json | 56 +- apps/desktop/src/locales/uk/messages.json | 36 +- apps/desktop/src/locales/vi/messages.json | 558 ++++++++++--------- apps/desktop/src/locales/zh_CN/messages.json | 34 +- apps/desktop/src/locales/zh_TW/messages.json | 32 +- 63 files changed, 2070 insertions(+), 558 deletions(-) diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index 999ec6d0dcd..f51b07b0a7f 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Instellings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "U aantekensessie het verstryk." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Is u seker u wil uitteken?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "U nuwe hoofwagwoord voldoen nie aan die beleidsvereistes nie." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "U kluisuittelling oorskry die beperkinge wat deur u organisasie daargestel is." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Outomatiese inskrywing" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index 5e7a4bb99d9..3b6957fccdb 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "الإعدادات" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "انتهت صلاحية جلسة الدخول." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "هل أنت متأكد من أنك تريد تسجيل الخروج؟" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "كلمة المرور الرئيسية الجديدة لا تفي بمتطلبات السياسة العامة." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "مهلة خزنتك تتجاوز القيود التي تضعها مؤسستك." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "التسجيل التلقائي" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "كلمة مرور الملف غير صالحة، الرجاء استخدام كلمة المرور التي أدخلتها عند إنشاء ملف التصدير." }, - "importDestination": { - "message": "وجهة الاستيراد" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "تعرف على خيارات الاستيراد الخاصة بك" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index 2c0bfbaf914..fa62ef1663d 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Ana parol ipucusu" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Ayarlar" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Seansın müddəti bitdi." }, + "restartRegistration": { + "message": "Qeydiyyatı yenidən başlat" + }, + "expiredLink": { + "message": "Vaxtı bitmiş keçid" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Lütfən qeydiyyatı yenidən başladın və ya giriş etməyə çalışın." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Artıq bir hesabınız ola bilər" + }, "logOutConfirmation": { "message": "Çıxış etmək istədiyinizə əminsiniz?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Yeni ana parolunuz siyasət tələblərini qarşılamır." }, - "receiveMarketingEmails": { - "message": "Elanlar, məsləhətlər və araşdırma fürsətləri üçün Bitwarden-dən e-poçt alın." + "receiveMarketingEmailsV2": { + "message": "Bitwarden-in tövsiyə, elan və araşdırma imkanlarını gələn qutunuzda əldə edin." }, "unsubscribe": { "message": "Abunəlikdən çıx" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Anbar vaxt bitişi, təşkilatınız tərəfindən ayarlanan məhdudiyyətləri aşır." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Avtomatik qeydiyyat" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Yararsız fayl parolu, lütfən xaricə köçürmə faylını yaradarkən daxil etdiyiniz parolu istifadə edin." }, - "importDestination": { - "message": "Hədəfi daxilə köçür" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Daxilə köçürmə seçimlərinizi öyrənin" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index d22164ccd34..e3c4f8f97ce 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Налады" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Тэрмін дзеяння вашага сеансу завяршыўся." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Вы сапраўды хочаце выйсці?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Ваш новы асноўны пароль не адпавядае патрабаванням палітыкі." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Час чакання вашага сховішча перавышае дазволеныя абмежаванні, якія прызначыла ваша арганізацыя." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Аўтаматычная рэгістрацыя" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index f2e55a33ef7..e6db6903e22 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Подсказка за главната парола" }, + "joinOrganization": { + "message": "Присъединяване към организацията" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Завършете присъединяването си към тази организация като зададете главна парола." + }, "settings": { "message": "Настройки" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Сесията ви изтече." }, + "restartRegistration": { + "message": "Рестартиране на регистрацията" + }, + "expiredLink": { + "message": "Връзка с изтекла давност" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Рестартирайте регистрацията или опитайте да се впишете." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Може вече да имате регистрация" + }, "logOutConfirmation": { "message": "Сигурни ли сте, че искате да се отпишете?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Паролата ви не отговаря на политиките." }, - "receiveMarketingEmails": { - "message": "Получавайте е-писма от Битоурден за новини, съвети и възможности за проучвания." + "receiveMarketingEmailsV2": { + "message": "Получавайте съвети, обявления и предложения за участие в проучвания от Битуорден в пощенската си кутия." }, "unsubscribe": { "message": "Отписване" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Времето за достъп до трезора Ви превишава ограничението, определено от организацията Ви." }, + "inviteAccepted": { + "message": "Поканата е приета" + }, "resetPasswordPolicyAutoEnroll": { "message": "Автоматично включване" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Неправилна парола за файла. Използвайте паролата, която сте въвели при създаването на изнесения файл." }, - "importDestination": { - "message": "Място на внасяне" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Научете повече относно възможностите за внасяне" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Данни" } } diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index fed7fb5babd..83437ea4573 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "সেটিংস" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "আপনার লগইন মাত্রকালটির মেয়াদ শেষ হয়ে গেছে।" }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "আপনি লগ আউট করতে চান?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "আপনার নতুন মূল পাসওয়ার্ড নীতির প্রয়োজনীয়তা পূরণ করে না।" }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 27c2fd94a4e..939fee08c76 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Postavke" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Sesija je istekla." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Da li ste sigurni da želite da se odjavite?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index d696fa2f4de..61744522b71 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Configuració" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "La vostra sessió ha caducat." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Segur que voleu tancar la sessió?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "La nova contrasenya principal no compleix els requisits de la política." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "El temps d'espera de la caixa forta supera les restriccions establertes per la vostra organització." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Inscripció automàtica" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "La contrasenya del fitxer no és vàlida. Utilitzeu la contrasenya que vau introduir quan vau crear el fitxer d'exportació." }, - "importDestination": { - "message": "Destinació de la importació" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Obteniu informació sobre les opcions d'importació" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 104fe42ee97..d28b464fdd4 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Nápověda k hlavnímu heslu" }, + "joinOrganization": { + "message": "Přidat se k organizaci" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Dokončete připojení k této organizaci nastavením hlavního hesla." + }, "settings": { "message": "Nastavení" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Platnost přihlášení vypršela." }, + "restartRegistration": { + "message": "Restartovat registraci" + }, + "expiredLink": { + "message": "Platnost odkazu vypršela" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Restartujte registraci nebo se zkuste přihlásit." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Už možná máte účet" + }, "logOutConfirmation": { "message": "Opravdu se chcete odhlásit?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Vaše nové hlavní heslo nesplňuje požadavky zásad." }, - "receiveMarketingEmails": { - "message": "Získejte e-maily od Bitwardenu pro oznámení, poradenství a výzkumné příležitosti." + "receiveMarketingEmailsV2": { + "message": "Dostávejte do své e-mailové schránky rady, oznámení a příležitosti k výzkumu od společnosti Bitwarden." }, "unsubscribe": { "message": "Odhlásit odběr" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Časový limit Vašeho trezoru překračuje omezení stanovená Vaší organizací." }, + "inviteAccepted": { + "message": "Pozvánka byla přijata" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatická registrace" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Neplatné heslo souboru, použijte heslo zadané při vytvoření souboru exportu." }, - "importDestination": { - "message": "Cíl importu" + "destination": { + "message": "Cíl" }, "learnAboutImportOptions": { "message": "Více o volbách importu" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index f3ec2e86180..3cb285cf21c 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index 082432368f4..b99ec3b53b0 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Hovedadgangskodetip" }, + "joinOrganization": { + "message": "Bliv medlem af organisation" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Færdiggør tilmeldingen til denne organisation ved at opsætte en hovedadgangskode." + }, "settings": { "message": "Indstillinger" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Loginsessionen er udløbet." }, + "restartRegistration": { + "message": "Genstart registrering" + }, + "expiredLink": { + "message": "Udløbet link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Genstart registreringen, eller prøv at logge ind." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Har allerede oprettet en konto?" + }, "logOutConfirmation": { "message": "Sikker på, at du vil logge ud?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Din nye hovedadgangskode opfylder ikke politikkravene." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Få råd, bekendtgørelser og forskningsmuligheder fra Bitwarden i indbakken." }, "unsubscribe": { "message": "Afmeld" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Din boks-timeout overskrider de organisationsbestemte restriktioner." }, + "inviteAccepted": { + "message": "Invitation accepteret" + }, "resetPasswordPolicyAutoEnroll": { "message": "Auto-indrullering" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Ugyldig filadgangskode. Brug samme adgangskode som under oprettelsen af eksportfilen." }, - "importDestination": { - "message": "Importdestination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Læs om importmuligheder" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 8651b06434a..cee6ad0f4bb 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master-Passwort-Hinweis" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Einstellungen" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Deine Sitzung ist abgelaufen." }, + "restartRegistration": { + "message": "Registrierung neu starten" + }, + "expiredLink": { + "message": "Abgelaufener Link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Bitte starte die Registrierung erneut oder versuche dich anzumelden." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Du hast möglicherweise bereits ein Konto" + }, "logOutConfirmation": { "message": "Bist du sicher, dass du dich abmelden willst?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Dein neues Masterpasswort entspricht nicht den Anforderungen der Richtlinie." }, - "receiveMarketingEmails": { - "message": "Erhalte E-Mails von Bitwarden für Ankündigungen, Ratschläge und Forschungsmöglichkeiten." + "receiveMarketingEmailsV2": { + "message": "Erhalte Ratschläge, Ankündigungen und Marktforschungsumfragen von Bitwarden in deinem Posteingang." }, "unsubscribe": { "message": "Deabonnieren" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Dein Tresor-Timeout überschreitet die von deinem Unternehmen festgelegten Beschränkungen." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatische Registrierung" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Ungültiges Dateipasswort. Bitte verwende das Passwort, das du beim Erstellen der Exportdatei eingegeben hast." }, - "importDestination": { - "message": "Import-Ziel" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Erfahre mehr über deine Importoptionen" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index 546b87086f7..b64dbaaa9a8 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -101,7 +101,7 @@ "message": "Επεξεργασία αντικειμένου" }, "emailAddress": { - "message": "Διεύθυνση ηλεκτρονικού ταχυδρομείου" + "message": "Διεύθυνση ηλ. ταχυδρομείου" }, "verificationCodeTotp": { "message": "Κωδικός Επαλήθευσης (TOTP)" @@ -527,7 +527,7 @@ "message": "Υπόδειξη κύριου κωδικού πρόσβασης (προαιρετικό)" }, "masterPassHintText": { - "message": "Αν ξεχάσετε τον κωδικό πρόσβασής σας, η υπενθύμιση του κωδικού πρόσβασης μπορεί να σταλεί στο email σας. $CURRENT$/$MAXIMUM$ μέγιστοι χαρακτήρες.", + "message": "Αν ξεχάσετε τον κωδικό πρόσβασής σας, η υπενθύμιση του κωδικού πρόσβασης μπορεί να σταλεί στο ηλ. ταχυδρομείο σας. $CURRENT$/$MAXIMUM$ μέγιστοι χαρακτήρες.", "placeholders": { "current": { "content": "$1", @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Υπόδειξη κύριου κωδικού πρόσβασης" }, + "joinOrganization": { + "message": "Συμμετοχή στον οργανισμό" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Ολοκληρώστε τη συμμετοχή σας σε αυτόν τον οργανισμό ορίζοντας έναν κύριο κωδικό πρόσβασης." + }, "settings": { "message": "Ρυθμίσεις" }, @@ -558,7 +564,7 @@ "message": "Υπόδειξη κωδικού πρόσβασης" }, "enterEmailToGetHint": { - "message": "Εισάγετε τη διεύθυνση ηλεκτρονικού ταχυδρομείου του λογαριασμού σας για να λάβετε την υπόδειξη του κύριου κωδικού πρόσβασης." + "message": "Εισάγετε τη διεύθυνση ηλ. ταχυδρομείου του λογαριασμού σας για να λάβετε την υπόδειξη του κύριου κωδικού πρόσβασης." }, "getMasterPasswordHint": { "message": "Λήψη υπόδειξης κύριου κωδικού" @@ -661,7 +667,7 @@ "message": "Να με θυμάσαι" }, "sendVerificationCodeEmailAgain": { - "message": "Επανάληψη αποστολής κωδικού επαλήθευσης μέσω ηλεκτρονικού ταχυδρομείου" + "message": "Επανάληψη αποστολής κωδικού επαλήθευσης μέσω ηλ. ταχυδρομείου" }, "useAnotherTwoStepMethod": { "message": "Χρήση άλλης μεθόδου σύνδεσης δύο βημάτων" @@ -709,7 +715,7 @@ "message": "Email" }, "emailDescV2": { - "message": "Εισάγετε έναν κωδικό που σας στάλθηκε στο email." + "message": "Εισάγετε τον κωδικό που σας στάλθηκε στο ηλ. ταχυδρομείο." }, "loginUnavailable": { "message": "Μη διαθέσιμη σύνδεση" @@ -792,6 +798,18 @@ "loginExpired": { "message": "Η περίοδος σύνδεσης σας έχει λήξει." }, + "restartRegistration": { + "message": "Επανεκκίνηση εγγραφής" + }, + "expiredLink": { + "message": "Ο σύνδεσμος έληξε" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Παρακαλούμε επανακκινήστε την εγγραφή ή δοκιμάστε να συνδεθείτε." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Μπορεί να έχετε ήδη λογαριασμό" + }, "logOutConfirmation": { "message": "Είστε βέβαιοι ότι θέλετε να αποσυνδεθείτε;" }, @@ -898,7 +916,7 @@ "message": "Μη έγκυρος κύριος κωδικός πρόσβασης" }, "twoStepLoginConfirmation": { - "message": "Η σύνδεση δύο βημάτων καθιστά τον λογαριασμό σας πιο ασφαλή απαιτώντας από εσάς να επαληθεύσετε τη σύνδεσή σας με άλλη συσκευή, όπως ένα κλειδί ασφαλείας, μία εφαρμογή αυθεντικοποίησης, ένα SMS, μία τηλεφωνική κλήση, ή ένα μήνυμα ηλεκτρονικού ταχυδρομείου. Η σύνδεση δύο βημάτων μπορεί να ρυθμιστεί στο διαδικτυακό θησαυ/κιο bitwarden.com. Θέλετε να επισκεφθείτε την ιστοσελίδα τώρα;" + "message": "Η σύνδεση δύο βημάτων καθιστά τον λογαριασμό σας πιο ασφαλή απαιτώντας από εσάς να επαληθεύσετε τη σύνδεσή σας με άλλη συσκευή, όπως ένα κλειδί ασφαλείας, μία εφαρμογή αυθεντικοποίησης, ένα SMS, μία τηλεφωνική κλήση, ή ένα μήνυμα ηλ. ταχυδρομείου. Η σύνδεση δύο βημάτων μπορεί να ρυθμιστεί στο διαδικτυακό θησαυ/κιο bitwarden.com. Θέλετε να επισκεφθείτε την ιστοσελίδα τώρα;" }, "twoStepLogin": { "message": "Σύνδεση δύο βημάτων" @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Ο νέος κύριος κωδικός δεν πληροί τις απαιτήσεις πολιτικής." }, - "receiveMarketingEmails": { - "message": "Αποκτήστε μηνύματα ηλεκτρονικού ταχυδρομείου από το Bitwarden για ανακοινώσεις, συμβουλές και ερευνητικές ευκαιρίες." + "receiveMarketingEmailsV2": { + "message": "Λάβετε συμβουλές, ανακοινώσεις και ευκαιρίες έρευνας από το Bitwarden στα εισερχόμενά σας." }, "unsubscribe": { "message": "Ακύρωση συνδρομής" @@ -1968,10 +1986,10 @@ "message": "Μία ή περισσότερες οργανωτικές πολιτικές επηρεάζουν τις επιλογές send σας." }, "emailVerificationRequired": { - "message": "Απαιτείται επαλήθευση ηλεκτρονικού ταχυδρομείου" + "message": "Απαιτείται επαλήθευση διεύθυνσης ηλ. ταχυδρομείου" }, "emailVerifiedV2": { - "message": "Email επιβεβαιωμένο" + "message": "Η διεύθυνση ηλ. ταχυδρομείου επιβεβαιώθηκε" }, "emailVerificationRequiredDesc": { "message": "Πρέπει να επαληθεύσετε το email σας για να χρησιμοποιήσετε αυτή τη δυνατότητα." @@ -2028,7 +2046,7 @@ "message": "Χρήση βιομετρικών" }, "enterVerificationCodeSentToEmail": { - "message": "Εισάγετε τον κωδικό επαλήθευσης που έχει σταλεί στο ηλεκτρονικό ταχυδρομείο σας." + "message": "Εισάγετε τον κωδικό επαλήθευσης που έχει σταλεί στο ηλ. ταχυδρομείο σας." }, "resendCode": { "message": "Επαναποστολή κωδικού" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Το χρονικό όριο του vault σας υπερβαίνει τους περιορισμούς που έχει ορίσει ο οργανισμός σας." }, + "inviteAccepted": { + "message": "Η πρόσκληση έγινε αποδεκτή" + }, "resetPasswordPolicyAutoEnroll": { "message": "Αυτόματη εγγραφή" }, @@ -2208,14 +2229,14 @@ "message": "Τύπος ονόματος χρήστη" }, "plusAddressedEmail": { - "message": "Συν διεύθυνση ηλεκτρονικού ταχυδρομείου", + "message": "Συν διεύθυνση ηλ. ταχυδρομείου", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { "message": "Χρησιμοποιήστε τις δυνατότητες δευτερεύουσας διεύθυνσης του παρόχου email σας." }, "catchallEmail": { - "message": "Ηλεκτρονικό ταχυδρομείο για κάθε σκοπό" + "message": "Ηλ. ταχυδρομείο κάθε σκοπού" }, "catchallEmailDesc": { "message": "Χρησιμοποιήστε τα διαμορφωμένα εισερχόμενα catch-all του domain σας." @@ -2242,7 +2263,7 @@ "message": "Αναζήτηση στο θησαυ/κιό μου" }, "forwardedEmail": { - "message": "Προωθημένο ψευδώνυμο ηλεκτρονικού ταχυδρομείου" + "message": "Προωθημένο ψευδώνυμο διεύθυνσης ηλ. ταχυδρομείου" }, "forwardedEmailDesc": { "message": "Δημιουργήστε ένα alias email με μια εξωτερική υπηρεσία προώθησης." @@ -2300,7 +2321,7 @@ } }, "forwarderNoAccountId": { - "message": "Αδύνατη η απόκτηση του $SERVICENAME$ καμουφλαρισμένου email ID.", + "message": "Αδύνατη η απόκτηση του $SERVICENAME$ καμουφλαρισμένου ID διεύθυνσης ηλ. ταχυδρομείου.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2381,7 +2402,7 @@ "message": "Σύνδεση ως" }, "rememberEmail": { - "message": "Απομνημόνευση ηλεκτρονικού ταχυδρομείου" + "message": "Απομνημόνευση διεύθυνσης ηλ. ταχυδρομείου" }, "notYou": { "message": "Όχι εσείς;" @@ -2503,22 +2524,22 @@ "message": "Δημιουργία λογαριασμού στο" }, "checkYourEmail": { - "message": "Ελέγξτε το email σας" + "message": "Ελέγξτε το ηλ. ταχυδρομείο σας" }, "followTheLinkInTheEmailSentTo": { - "message": "Ακολουθήστε το σύνδεσμο στο email που στάλθηκε στο" + "message": "Ακολουθήστε το σύνδεσμο στο μήνυμα ηλ. ταχυδρομείου που στάλθηκε στο" }, "andContinueCreatingYourAccount": { "message": "και συνεχίστε στη δημιουργία του λογαριασμού σας." }, "noEmail": { - "message": "Όχι email;" + "message": "Κανένα μήνυμα ηλ. ταχυδρομείου;" }, "goBack": { "message": "Μετάβαση πίσω" }, "toEditYourEmailAddress": { - "message": "για να επεξεργαστείτε τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας." + "message": "για να επεξεργαστείτε τη διεύθυνση ηλ. ταχυδρομείου σας." }, "exposedMasterPassword": { "message": "Εκτεθειμένος Κύριος Κωδικός Πρόσβασης" @@ -2618,7 +2639,7 @@ "message": "Η σύνδεση εγκρίθηκε" }, "userEmailMissing": { - "message": "Το ηλεκτρονικό ταχυδρομείο του χρήστη λείπει" + "message": "Η διεύθυνση ηλ. ταχυδρομείου του χρήστη λείπει" }, "deviceTrusted": { "message": "Αξιόπιστη συσκευή" @@ -2678,14 +2699,14 @@ } }, "multipleInputEmails": { - "message": "1 ή περισσότερα ηλεκτρονικά ταχυδρομεία δεν είναι έγκυρα" + "message": "1 ή περισσότερες διευθύνσεις ηλ. ταχυδρομείου δεν είναι έγκυρες" }, "inputTrimValidator": { "message": "Η καταχώρηση δεν πρέπει να περιέχει μόνο κενά.", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "Η καταχώρηση δεν είναι διεύθυνση ηλεκτρονικού ταχυδρομείου." + "message": "Η καταχώρηση δεν είναι διεύθυνση ηλ. ταχυδρομείου." }, "fieldsNeedAttention": { "message": "$COUNT$ πεδίο(α) παραπάνω χρειάζονται την προσοχή σας.", @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Μη έγκυρος κωδικός πρόσβασης, παρακαλώ χρησιμοποιήστε τον κωδικό πρόσβασης που εισαγάγατε όταν δημιουργήσατε το αρχείο εξαγωγής." }, - "importDestination": { - "message": "Προορισμός εισαγωγής" + "destination": { + "message": "Προορισμός" }, "learnAboutImportOptions": { "message": "Μάθετε για τις επιλογές εισαγωγής σας" @@ -2892,7 +2913,7 @@ "message": "Συμπερίληψη κοινόχρηστων φακέλων" }, "lastPassEmail": { - "message": "Διεύθυνση ηλεκτρονικού ταχυδρομείου LastPass" + "message": "Διεύθυνση ηλ. ταχυδρομείου LastPass" }, "importingYourAccount": { "message": "Εισαγωγή του λογαριασμού σας..." @@ -2932,7 +2953,7 @@ "message": "Εισαγωγή από CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Δοκιμάστε ξανά ή ψάξτε για ένα μήνυμα ηλεκτρονικού ταχυδρομείου από το LastPass για να επιβεβαιώσετε ότι είστε εσείς." + "message": "Δοκιμάστε ξανά ή ψάξτε για ένα μήνυμα ηλ. ταχυδρομείου από το LastPass για να επιβεβαιώσετε ότι είστε εσείς." }, "collection": { "message": "Συλλογή" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Δεδομένα" } } diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index bd439742edc..62ae99fc7b8 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organisation" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organisation by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organisation." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrolment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index 1cc1e2235ae..ced2fc61e31 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organisation" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organisation by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 02bf89abf31..9cf5ef6f60b 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index 2e9a6752433..d71866a8f18 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Pista de la contraseña maestra" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Ajustes" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Tu sesión ha expirado." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "¿Estás seguro de querer cerrar sesión?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Su nueva contraseña maestra no cumple con los requisitos de la política." }, - "receiveMarketingEmails": { - "message": "Obtén correos electrónicos de Bitwarden para anuncios, consejos y oportunidades de investigación." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Darse de baja" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "El tiempo de espera de tu caja fuerte excede las restricciones establecidas por tu organización." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Inscripción automática" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Contraseña de archivo no válida, por favor utiliza la contraseña que introdujiste cuando creaste el archivo de exportación." }, - "importDestination": { - "message": "Destino de importación" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Aprende acerca de tus opciones de importación" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index 736e14845b7..f746cbb30f1 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Seaded" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Sessioon on aegunud." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Oled kindel, et soovid välja logida?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Uus ülemparool ei vasta eeskirjades väljatoodud tingimustele." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Valitud hoidla ajalõpp ei ole organisatsiooni poolt määratud reeglitega kooskõlas." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automaatne liitumine" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index 58e77b10920..c0f8e046429 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Ezarpenak" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Saioa amaitu da." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Ziur zaude saioa itxi nahi duzula?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Zure pasahitz nagusi berriak ez ditu baldintzak betetzen." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Zure kutxa gotorreko itxaronaldiak, zure erakundeak ezarritako murrizpenak gainditzen ditu." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Izen-emate automatikoa" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index 3f20bd7a58e..d435e1fdde3 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "تنظیمات" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "نشست ورود شما منقضی شده است." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "آیا مطمئنید که می‌خواهید خارج شوید؟" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "کلمه عبور اصلی جدید شما از شرایط سیاست پیروی نمی‌کند." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "مهلت زمانی شما بیش از محدودیت های تعیین شده توسط سازمانتان است." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "ثبت نام خودکار" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "مقصد برون ریزی" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 5f7eb42dacf..7b8f8c691a1 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Pääsalasanan vihje" }, + "joinOrganization": { + "message": "Liity organisaatioon" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Viimeistele organisaatioon liittyminen asettamalla pääsalasana." + }, "settings": { "message": "Asetukset" }, @@ -628,7 +634,7 @@ "message": "Todennuskoodi vaaditaan." }, "webauthnCancelOrTimeout": { - "message": "Todennus peruutettiin tai siinä kesti liian kauan. Yritä uudelleen." + "message": "Tunnistautuminen peruttiin tai se kesti liian kauan. Yritä uudelleen." }, "invalidVerificationCode": { "message": "Virheellinen todennuskoodi" @@ -664,7 +670,7 @@ "message": "Lähetä todennuskoodi sähköpostitse uudelleen" }, "useAnotherTwoStepMethod": { - "message": "Käytä eri kaksivaiheisen kirjautumisen todennusmenetelmää" + "message": "Käytä vaihtoehtoista todennustapaa" }, "insertYubiKey": { "message": "Kytke YubiKey-todennuslaitteesi tietokoneen USB-porttiin ja paina sen painiketta." @@ -792,6 +798,18 @@ "loginExpired": { "message": "Kirjautumisistuntosi on erääntynyt." }, + "restartRegistration": { + "message": "Aloita rekisteröityminen alusta" + }, + "expiredLink": { + "message": "Vanhentunut linkki" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Aloita rekisteröityminen alusta tai yritä kirjautua sisään uudelleen." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Sinulla saattaa olla jo tili" + }, "logOutConfirmation": { "message": "Haluatko varmasti kirjautua ulos?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Uusi pääsalasanasi ei täytä käytännön määrittämiä vaatimuksia." }, - "receiveMarketingEmails": { - "message": "Vastaanota Bitwardenilta uutiskirjeitä julkaisuista, tukiresursseista ja tutkimusmahdollisuuksista." + "receiveMarketingEmailsV2": { + "message": "Vastaanota Bitwardenilta postilaatikkoosi vinkkejä, uutisia ja tutkimusmahdollisuuksia." }, "unsubscribe": { "message": "Lopeta tilaus" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Holvisi aikakatkaisu ylittää organisaatiosi asettamat rajoitukset." }, + "inviteAccepted": { + "message": "Kutsu hyväksyttiin" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automaattinen liitos" }, @@ -2782,7 +2803,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Virhe yhdistettäessä Duo-palveluun. Käytä toista kaksivaiheista kirjautumismenetelmää tai ota yhteyttä Duoon saadaksesi apua." + "message": "Virhe yhdistettäessä Duo-palveluun. Käytä vaihtoehtoista todennustapaa tai ole yhteydessä Duon asiakaspalveluun saadaksesi apua." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Tiedoston salasana on virheellinen. Käytä vientitiedoston luonnin yhteydessä syötettyä salasanaa." }, - "importDestination": { - "message": "Tuontikohde" + "destination": { + "message": "Määränpää" }, "learnAboutImportOptions": { "message": "Lue lisää tuontivaihtoehdoista" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Tiedot" } } diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index 9a767f2e007..7e7d5485eea 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Mga Preperensya" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Nag-expire na ang iyong session sa login." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Sigurado ka bang gusto mong mag-log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Ang iyong bagong master password ay hindi nakakatugon sa mga kinakailangan sa patakaran." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Ang iyong vault timeout ay lumalampas sa mga restriksiyon na itinakda ng iyong organisasyon." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Awtomatikong pagpapatala" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 4bba4978d2d..f1e178410d8 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Paramètres" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Votre session a expiré." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Êtes-vous sûr de vouloir vous déconnecter ?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Votre nouveau mot de passe principal ne répond pas aux exigences de politique de sécurité." }, - "receiveMarketingEmails": { - "message": "Recevez des courriels de Bitwarden pour des annonces, des conseils et des opportunités de recherche." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Se désabonner" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Le délai d'expiration de votre coffre dépasse les restrictions définies par votre organisation." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Inscription automatique" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Mot de passe du fichier incorrect, veuillez utiliser le mot de passe saisi lors de l'exportation du fichier." }, - "importDestination": { - "message": "Destination de l'import" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "En savoir plus sur vos options d'importation" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index 9ca3726f0c4..6d0573130ff 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index c2e3febcbd0..61f784ce7eb 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "הגדרות" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "תוקף החיבור שלך הסתיים." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "האם אתה בטוח שברצונך להתנתק?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "הסיסמה הראשית החדשה השלך לא עומדת בדרישות המדיניות." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "הזמן הקצוב לכספת שלך חורג מהמגבלות שנקבעו על ידי הארגון שלך." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "רישום אוטומטי" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index e4f6d33e64d..a0eedecd256 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index 5999ffe078b..895ec2ab378 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Postavke" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Sesija je istekla." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Sigurno se želiš odjaviti?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Tvoja nova glavna lozinka ne ispunjava zahtjeve." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Vrijeme isteka premašuje ograničenje koju je postavila tvoja organizacija." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatsko učlanjenje" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Nesipravna lozinka datoteke. Unesi lozinku izvozne datoteke." }, - "importDestination": { - "message": "Odredište uvoza" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Više o mogućnostima uvoza" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 082adad666e..e699667a6a4 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Mesterjelszó emlékeztető" }, + "joinOrganization": { + "message": "Csatlakozás szervezethez" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Fejezzük be a szervezethez csatlakozást egy mesterjelszó beállításával." + }, "settings": { "message": "Beállítások" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "A bejelentkezési munkamenet lejárt." }, + "restartRegistration": { + "message": "Regisztráció újra indítása" + }, + "expiredLink": { + "message": "A hivatkozás lejárt." + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "A Bitwarden képes tárolni és kitölteni a kétlépcsős ellenőrző kódokat. Válasszuk a kamera ikont, hogy képernyőképet készítsünk a webhely hitelesítő QR kódjáról vagy másoljuk ki és illesszük be a kulcsot ebbe a mezőbe." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Már rendelkezünkk fiókkal." + }, "logOutConfirmation": { "message": "Biztosan szeretnénk kijelentkezni?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Az új mesterjelszó nem felel meg a szabály követelményeknek." }, - "receiveMarketingEmails": { - "message": "Emaileket kaphatunk a Bitwardentől bejelentésekről, tanácsokról és kutatási lehetőségekről." + "receiveMarketingEmailsV2": { + "message": "Tanácsokat, bejelentéseket és kutatási lehetőségeket kaphatunk a Bitwardentől a postaládába." }, "unsubscribe": { "message": "Leiratkozás" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "A széf időkorlátja túllépi a szervezet által beállított korlátozást." }, + "inviteAccepted": { + "message": "A meghívás elfogadásra került." + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatikus regisztráció" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "A fájl jelszó érvénytelen. Használjuk az exportfájl létrehozásakor megadott jelszót." }, - "importDestination": { - "message": "Importálás leírás" + "destination": { + "message": "Cél" }, "learnAboutImportOptions": { "message": "Információ az importálási opciókról" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Adat" } } diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index 52e331ec600..2e822e292ac 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Setelan" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Sesi masuk Anda telah berakhir." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Anda yakin ingin keluar?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Kata sandi utama Anda yang baru tidak memenuhi persyaratan kebijakan." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Waktu tunggu brankas Anda melebihi batasan yang diatur organisasi Anda." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Pendaftaran otomatis" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index b63e8e46e74..ab23afe2773 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Impostazioni" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "La tua sessione è scaduta." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Sei sicuro di voler uscire?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "La tua nuova password principale non soddisfa i requisiti di sicurezza." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Il timeout della tua cassaforte supera i limiti impostati dalla tua organizzazione." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Iscrizione automatica" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Password errata, usa la password che hai inserito alla creazione del file di esportazione." }, - "importDestination": { - "message": "Destinazione dell'importazione" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Ulteriori informazioni sulle tue opzioni di importazione" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 32fb3e07bdf..8eb3510bc17 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "マスターパスワードのヒント" }, + "joinOrganization": { + "message": "組織に参加" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "マスターパスワードを設定して、この組織への参加を完了します。" + }, "settings": { "message": "設定" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "ログインセッションの有効期限が切れています。" }, + "restartRegistration": { + "message": "登録を再度始める" + }, + "expiredLink": { + "message": "期限切れのリンク" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "登録を再度始めるか、ログインしてください。" + }, + "youMayAlreadyHaveAnAccount": { + "message": "すでにアカウントを持っている可能性があります" + }, "logOutConfirmation": { "message": "ログアウトしてもよろしいですか?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "新しいマスターパスワードは最低要件を満たしていません。" }, - "receiveMarketingEmails": { - "message": "Bitwarden からのお知らせ、アドバイス、アンケート調査等のメールを受信します。" + "receiveMarketingEmailsV2": { + "message": "Bitwarden からメールでアドバイスやお知らせ、リサーチの機会を受け取りましょう。" }, "unsubscribe": { "message": "配信停止" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "保管庫のタイムアウトが組織によって設定された制限を超えています。" }, + "inviteAccepted": { + "message": "招待が承認されました" + }, "resetPasswordPolicyAutoEnroll": { "message": "自動登録" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "無効なファイルパスワードです。エクスポートファイルを作成したときに入力したパスワードを使用してください。" }, - "importDestination": { - "message": "インポート先" + "destination": { + "message": "保存先" }, "learnAboutImportOptions": { "message": "インポートオプションの詳細" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "データ" } } diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 9ca3726f0c4..6d0573130ff 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index 9ca3726f0c4..6d0573130ff 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index 1f6843e86a3..46fbbb6d230 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "ಸೆಟ್ಟಿಂಗ್‍ಗಳು" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "ನಿಮ್ಮ ಲಾಗಿನ್ ಸೆಷನ್ ಅವಧಿ ಮೀರಿದೆ." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "ಲಾಗ್ ಔಟ್ ಮಾಡಲು ನೀವು ಖಚಿತವಾಗಿ ಬಯಸುವಿರಾ?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "ನಿಮ್ಮ ಹೊಸ ಮಾಸ್ಟರ್ ಪಾಸ್‌ವರ್ಡ್ ನೀತಿಯ ಅವಶ್ಯಕತೆಗಳನ್ನು ಪೂರೈಸುವುದಿಲ್ಲ." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 62d4ccec61a..01d8550a720 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "설정" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "로그인 세션이 만료되었습니다." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "정말 로그아웃하시겠습니까?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "새 마스터 비밀번호가 정책 요구 사항을 따르지 않습니다." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "볼트 제한 시간이 조직에서 설정한 제한을 초과합니다." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "자동 등록" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index 74cf0ef9637..bca956d3e3c 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Nustatymai" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Sesijos laikas baigėsi." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Ar tikrai norite atsijungti?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Jūsų naujasis pagrindinis slaptažodis neatitinka politikos reikalavimų." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Jūsų saugyklos skirtasis laikas viršija jūsų organizacijos nustatytus apribojimus." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatinis įtraukimas" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Netinkamas failo slaptažodis, prašome naudoti tą slaptažodį, kurį įvedėte kurdami eksportuojamą failą." }, - "importDestination": { - "message": "Importavimo vieta" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Sužinoti apie importavimo pasirinkimus" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 36f089d935d..768bd8b83d6 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Galvenās paroles norāde" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Iestatījumi" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Pieteikšanās sesija ir beigusies." }, + "restartRegistration": { + "message": "Sākt reģistrēšanos no jauna" + }, + "expiredLink": { + "message": "Saitei beidzies derīgums" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Lūgums sākt reģistrēšanos no jauna vai mēģināt pieteikties." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Tev jau varētu būt konts" + }, "logOutConfirmation": { "message": "Vai tiešām atteikties?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Jaunā galvenā parole neatbilst nosacījumu prasībām." }, - "receiveMarketingEmails": { - "message": "Saņemt e-pasta ziņojumus no Bitwarden par paziņojumiem, padomiem un izpētes iespējām." + "receiveMarketingEmailsV2": { + "message": "Iegūt savā iesūtnē padomus, paziņojumus un izpētes iespējas no Bitwarden." }, "unsubscribe": { "message": "Atteikt abonēšanu" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Glabātavas noildze pārsniedz apvienības uzstādītos ierobežojumus." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automātiska ievietošana sarakstā" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Nederīga datnes parole, lūgums izmantot to paroli, kas tika ievadīta izgūšanas datnes izveidošanas brīdī." }, - "importDestination": { - "message": "Ievietošanas galamērķis" + "destination": { + "message": "Galamērķis" }, "learnAboutImportOptions": { "message": "Uzzināt par ievietošanas iespējām" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Dati" } } diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index bc6ee3c51a8..6c70b5e5e6c 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Podešavanja" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Vaša sesija je istekla." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Jeste li sigurni da se želite odjaviti?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index 9ab12aabecd..bd1e9dbd15f 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "ക്രമീകരണങ്ങള്‍" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "നിങ്ങളുടെ പ്രവർത്തന സമയം കഴിഞ്ഞിരിക്കുന്നു." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "നിങ്ങൾക്ക് ലോഗ് ഔട്ട് ചെയ്യണമെന്ന് ഉറപ്പാണോ?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "നിങ്ങളുടെ പുതിയ മാസ്റ്റർ പാസ്‌വേഡ് നയ ആവശ്യകതകൾ നിറവേറ്റുന്നില്ല." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index 9ca3726f0c4..6d0573130ff 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index 99b8001d97f..e09bc197d72 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index 3265be0677b..fb2430e75e1 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Innstillinger" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Din innloggingsøkt har utløpt." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Er du sikker på at du vil logge av?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Det nye hovedpassordet ditt oppfyller ikke vilkårene." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Tidsavbruddet ditt for hvelvet overstiger begrensningene som er satt av organisasjonen din." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatisk registrering" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Lær mer om importalternativene dine" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index 8598b501e9e..ecce20d5cb8 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index e8dc5c18c2b..f143382c846 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Hoofdwachtwoordhint" }, + "joinOrganization": { + "message": "Lid van organisatie worden" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Voltooi je lidmaatschap aan deze organisatie door een hoofdwachtwoord in te stellen." + }, "settings": { "message": "Instellingen" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Je inlogsessie is verlopen." }, + "restartRegistration": { + "message": "Registratie herstarten" + }, + "expiredLink": { + "message": "Verlopen link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Herstart de registratie of probeer in te loggen." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Je hebt al een account" + }, "logOutConfirmation": { "message": "Weet je zeker dat je wilt uitloggen?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Je nieuwe hoofdwachtwoord voldoet niet aan de beleidseisen." }, - "receiveMarketingEmails": { - "message": "Ontvang e-mailberichten van Bitwarden voor aankondigingen, advies en onderzoeksmogelijkheden." + "receiveMarketingEmailsV2": { + "message": "Krijg advies, aankondigingen en onderzoeksmogelijkheden van Bitwarden in je inbox." }, "unsubscribe": { "message": "Afmelden" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Je kluis time-out is hoger dan het maximum van jouw organisatie." }, + "inviteAccepted": { + "message": "Uitnodiging geaccepteerd" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatische inschrijving" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Onjuist bestandswachtwoord, gebruik het wachtwoord dat je hebt ingevoerd bij het aanmaken van het exportbestand." }, - "importDestination": { - "message": "Importbestemming" + "destination": { + "message": "Bestemming" }, "learnAboutImportOptions": { "message": "Leer meer over je importopties" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Gegevens" } } diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index c024eed6de0..ca99bfcbe47 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Innstillingar" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Innloggingsøkta di har gått ut." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Er du sikker på at du vil logge ut?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index 88ce5d5d346..da8b7401ffc 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index ea717d0157e..06ceca87e97 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Podpowiedź do hasła głównego" }, + "joinOrganization": { + "message": "Dołącz do organizacji" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Zakończ dołączanie do tej organizacji przez ustawienie hasła głównego." + }, "settings": { "message": "Ustawienia" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Twoja sesja wygasła." }, + "restartRegistration": { + "message": "Zrestartuj rejestrację" + }, + "expiredLink": { + "message": "Link wygasł" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Zrestartuj rejestrację lub spróbuj się zalogować." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Możesz mieć już konto" + }, "logOutConfirmation": { "message": "Czy na pewno chcesz się wylogować?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Nowe hasło główne nie spełnia wymaganych zasad." }, - "receiveMarketingEmails": { - "message": "Otrzymuj e-maile od Bitwarden z ogłoszeniami, poradami i badaniami." + "receiveMarketingEmailsV2": { + "message": "Uzyskaj poradę, ogłoszenia i możliwości badawcze od Bitwarden w swojej skrzynce odbiorczej." }, "unsubscribe": { "message": "Anuluj subskrypcję" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Czas blokowania sejfu przekracza limit określony przez organizację." }, + "inviteAccepted": { + "message": "Zaproszenie zostało zaakceptowane" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatyczne rejestrowanie użytkowników" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Hasło do pliku jest nieprawidłowe. Użyj hasła które podano przy tworzeniu pliku eksportu." }, - "importDestination": { - "message": "Miejsce docelowe importu" + "destination": { + "message": "Miejsce docelowe" }, "learnAboutImportOptions": { "message": "Dowiedz się więcej o opcjach importu" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Dane" } } diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index 3c8321af347..b330517b37e 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Configurações" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "A sua sessão expirou." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Você tem certeza que deseja sair?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "A sua nova senha mestra não cumpre aos requisitos da política." }, - "receiveMarketingEmails": { - "message": "Obtenha e-mails do Bitwarden para anúncios, conselhos e oportunidades de pesquisa." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Cancelar subscrição" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "O tempo limite do seu cofre excede as restrições definidas por sua organização." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Inscrição Automática" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Senha do arquivo inválida, por favor informe a senha utilizada quando criou o arquivo de exportação." }, - "importDestination": { - "message": "Destino da Importação" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Saiba mais sobre suas opções de importação" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index cc7fa764bf9..7e98dcae50e 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Dica da palavra-passe mestra" }, + "joinOrganization": { + "message": "Aderir à organização" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Conclua a adesão a esta organização ao definir uma palavra-passe mestra." + }, "settings": { "message": "Definições" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "A sua sessão expirou." }, + "restartRegistration": { + "message": "Reiniciar registo" + }, + "expiredLink": { + "message": "Link expirado" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Por favor, reinicie o registo ou tente iniciar sessão." + }, + "youMayAlreadyHaveAnAccount": { + "message": "É possível que já tenha uma conta" + }, "logOutConfirmation": { "message": "Tem a certeza de que pretende terminar sessão?" }, @@ -861,7 +879,7 @@ "description": "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." }, "goToWebVault": { - "message": "Ir para o cofre web" + "message": "Ir para o cofre Web" }, "getMobileApp": { "message": "Obter a aplicação móvel" @@ -1044,7 +1062,7 @@ "message": "Tema" }, "themeDesc": { - "message": "Alterar o tema de cores da aplicação." + "message": "Altere o tema de cores da aplicação." }, "dark": { "message": "Escuro", @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "A sua nova palavra-passe mestra não cumpre os requisitos da política." }, - "receiveMarketingEmails": { - "message": "Receba e-mails do Bitwarden com anúncios, conselhos e oportunidades de investigação." + "receiveMarketingEmailsV2": { + "message": "Receba conselhos, anúncios e oportunidades de investigação do Bitwarden na sua caixa de entrada." }, "unsubscribe": { "message": "Anular subscrição" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "O tempo limite do seu cofre excede as restrições definidas pela sua organização." }, + "inviteAccepted": { + "message": "Convite aceite" + }, "resetPasswordPolicyAutoEnroll": { "message": "Inscrição automática" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Palavra-passe de ficheiro inválida, utilize a palavra-passe que introduziu quando criou o ficheiro de exportação." }, - "importDestination": { - "message": "Destino da importação" + "destination": { + "message": "Destino" }, "learnAboutImportOptions": { "message": "Saiba mais sobre as suas opções de importação" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Dados" } } diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index 42a3879c42b..e62db26b816 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Setări" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Sesiunea de autentificare a expirat." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Sigur doriți să vă deconectați?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Noua dvs. parolă principală nu îndeplinește cerințele politicii." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Timpul de expirare al seifului depășește restricțiile stabilite de organizația dvs." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Înscriere automată" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index e09961b922e..fdb2e124830 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Подсказка к мастер-паролю" }, + "joinOrganization": { + "message": "Присоединиться к организации" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Завершите присоединение к этой организации, установив мастер-пароль." + }, "settings": { "message": "Настройки" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Истек срок действия вашего сеанса." }, + "restartRegistration": { + "message": "Перезапустить регистрацию" + }, + "expiredLink": { + "message": "Истекшая ссылка" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Пожалуйста, перезапустите регистрацию или попробуйте авторизоваться." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Возможно, у вас уже есть аккаунт" + }, "logOutConfirmation": { "message": "Вы действительно хотите выйти?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Ваш новый мастер-пароль не соответствует требованиям политики." }, - "receiveMarketingEmails": { - "message": "Получайте электронные письма от Bitwarden с анонсами, советами и возможностями для исследований." + "receiveMarketingEmailsV2": { + "message": "Получайте советы, анонсы и возможности для исследований от Bitwarden на свой email." }, "unsubscribe": { "message": "Отписаться" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Тайм-аут вашего хранилища превышает ограничения, установленные вашей организацией." }, + "inviteAccepted": { + "message": "Приглашение принято" + }, "resetPasswordPolicyAutoEnroll": { "message": "Автоматическое развертывание" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Неверный пароль к файлу. Используйте пароль, введенный при создании файла экспорта." }, - "importDestination": { - "message": "Цель импорта" + "destination": { + "message": "Назначение" }, "learnAboutImportOptions": { "message": "Узнайте о возможностях импорта" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Данные" } } diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index 3c069d841e5..b2f2469ccf3 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "සැකසුම්" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 636925a39dc..5edd4f4880a 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Nápoveda pre hlavné heslo" }, + "joinOrganization": { + "message": "Pripojte sa k organizácii" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Dokončite pripojenie k tejto organizácii nastavením hlavného hesla." + }, "settings": { "message": "Nastavenia" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Platnosť prihlásenia vypršala." }, + "restartRegistration": { + "message": "Zopakovať registráciu" + }, + "expiredLink": { + "message": "Platnosť odkazu vypršala" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Prosím, zopakujte registráciu alebo sa pokúste prihlásiť." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Možno už máte účet" + }, "logOutConfirmation": { "message": "Naozaj sa chcete odhlásiť?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Vaše nové hlavné heslo nespĺňa pravidlá." }, - "receiveMarketingEmails": { - "message": "Dostávať e-maily od Bitwardenu s oznámeniami, radami a možnosťami výskumu." + "receiveMarketingEmailsV2": { + "message": "Dostávajte do schránky rady, oznámenia a príležitosti na výskum od spoločnosti Bitwarden." }, "unsubscribe": { "message": "Odhlásiť sa z odberu" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Časový limit vášho trezora prekračuje obmedzenia nastavené vašou organizáciou." }, + "inviteAccepted": { + "message": "Pozvánka prijatá" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatická registrácia" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Neplatné heslo súboru, použite heslo, ktoré ste zadali pri vytváraní exportného súboru." }, - "importDestination": { - "message": "Cieľ importu" + "destination": { + "message": "Cieľ" }, "learnAboutImportOptions": { "message": "Zistiť viac o možnostiach importu" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Údaje" } } diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 0b82b67963d..7916795d1a4 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Nastavitve" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Vaša seja je potekla." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index d715a5062a9..4bb47264107 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Савет главне лозинке" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Подешавања" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Ваша сесија је истекла." }, + "restartRegistration": { + "message": "Поново покрените регистрацију" + }, + "expiredLink": { + "message": "Истекла веза" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Поново покрените регистрацију или покушајте да се пријавите." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Можда већ имате налог" + }, "logOutConfirmation": { "message": "Заиста желите да се одјавите?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Ваша нова главна лозинка не испуњава захтеве полисе." }, - "receiveMarketingEmails": { - "message": "Добијајте е-пошту од Bitwarden-а за најаве, савете и могућности истраживања." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Одјави се" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Време истека вашег сефа је премашило дозвољена ограничења од стране ваше организације." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Аутоматска пријава" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Неважећа лозинка за датотеку, користите лозинку коју сте унели када сте креирали датотеку за извоз." }, - "importDestination": { - "message": "Смештај увоза" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Сазнајте више о опцијама увоза" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Подаци" } } diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index 61abab33235..b164bb5f19e 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Huvudlösenordsledtråd" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Inställningar" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Din inloggningssession har löpt ut." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Är du säker på att du vill logga ut?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Ditt nya huvudlösenord uppfyller inte kraven i policyn." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Ditt valvs tid för timeout överskrider de begränsningar som fastställts av din organisation." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatiskt deltagande" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Ogiltigt fillösenord, använd lösenordet du angav när du skapade exportfilen." }, - "importDestination": { - "message": "Importdestination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Läs mer om dina importalternativ" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index 9ca3726f0c4..6d0573130ff 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "Your login session has expired." }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "Are you sure you want to log out?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index 97be1e3ecfa..2cd71c42ebb 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "การตั้งค่า" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "เซสชันของคุณหมดอายุแล้ว" }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "คุณแน่ใจว่าคุณต้องการที่จะออกจากระบบ?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 796b35c8181..49579f05845 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -527,7 +527,7 @@ "message": "Ana parola ipucu (isteğe bağlı)" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Parolanızı unutursanız parola ipucunuzu e-posta adresinize gönderebiliriz. Maksimum $CURRENT$/$MAXIMUM$ karakter.", "placeholders": { "current": { "content": "$1", @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Ana parola ipucu" }, + "joinOrganization": { + "message": "Kuruluşa katıl" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Kuruluşa katılmayı tamamlamak için ana parolanızı belirleyin." + }, "settings": { "message": "Ayarlar" }, @@ -682,7 +688,7 @@ "message": "Kimlik doğrulama uygulaması" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Kimlik doğrulama uygulamanızın (örn. Bitwarden Authenticator) ürettiği kodu girin.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { @@ -692,7 +698,7 @@ "message": "Hesabınıza erişmek için bir YubiKey kullanın. YubiKey 4, 4 Nano, 4C ve NEO cihazlarıyla çalışır." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Duo Security'nin ürettiği kodu girin.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -709,7 +715,7 @@ "message": "E-posta" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "E-posta adresinize gönderilen kodu girin." }, "loginUnavailable": { "message": "Giriş yapılamıyor" @@ -792,6 +798,18 @@ "loginExpired": { "message": "Oturumunuzun süresi doldu." }, + "restartRegistration": { + "message": "Kaydı yeniden başlat" + }, + "expiredLink": { + "message": "Bağlantının süresi dolmuş" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Lütfen kaydı yeniden başlatın veya giriş yapmayı deneyin." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Zaten hesabınız olabilir" + }, "logOutConfirmation": { "message": "Çıkmak istediğinize emin misiniz?" }, @@ -1352,7 +1370,7 @@ "description": "ex. Date this password was updated" }, "exportFrom": { - "message": "Export from" + "message": "Dışa aktarılacak konum" }, "exportVault": { "message": "Kasayı dışa aktar" @@ -1361,7 +1379,7 @@ "message": "Dosya biçimi" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "Dışarı aktarılan bu dosya parola korumalı olacak ve dosyanın çözülmesi için parolayı girmeniz gerekecek." }, "filePassword": { "message": "Dosya parolası" @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Yeni ana parolanız ilke gereksinimlerini karşılamıyor." }, - "receiveMarketingEmails": { - "message": "Bitwarden'dan duyurular, öneriler ve araştırmalarla ilgili e-postalar alın." + "receiveMarketingEmailsV2": { + "message": "Bitwarden'dan öneriler, duyurular ve araştırma fırsatları e-posta adresinize gelsin." }, "unsubscribe": { "message": "İstediğiniz zaman" @@ -1733,7 +1751,7 @@ "message": "Tarayıcı entegrasyonunu etkinleştirme hatası" }, "browserIntegrationErrorDesc": { - "message": "An error has occurred while enabling browser integration." + "message": "Tarayıcı entegrasyonu etkinleştirilirken bir hata oluştu." }, "browserIntegrationMasOnlyDesc": { "message": "Ne yazık ki tarayıcı entegrasyonu şu anda sadece Mac App Store sürümünde destekleniyor." @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Kasa zaman aşımınız, kuruluşunuz tarafından belirlenen kısıtlamaları aşıyor." }, + "inviteAccepted": { + "message": "Davet kabul edildi" + }, "resetPasswordPolicyAutoEnroll": { "message": "Otomatik eklenme" }, @@ -2175,7 +2196,7 @@ "message": "Kuruluş kasasını dışa aktarma" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "Yalnızca $ORGANIZATION$ ile ilişkili kuruluş kasası dışarı aktarılacak. Kişisel kasalardaki ve diğer kuruluşlardaki kayıtlar dahil edilmeyecek.", "placeholders": { "organization": { "content": "$1", @@ -2310,7 +2331,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Geçersiz $SERVICENAME$ alan adı.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -2320,7 +2341,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Geçersiz $SERVICENAME$ URL'si.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -2330,7 +2351,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Bilinmeyen $SERVICENAME$ hatası oluştu.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -2340,7 +2361,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "Bilinmeyen yönlendirici: '$SERVICENAME$'.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Geçersiz dosya parolası. Lütfen dışa aktardığınız dosyayı oluştururken girdiğiniz parolayı kullanın." }, - "importDestination": { - "message": "İçe aktarma hedefi" + "destination": { + "message": "Hedef" }, "learnAboutImportOptions": { "message": "İçe aktarma seçeneklerinizi öğrenin" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Veri" } } diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 30c2034b2ae..b787172d170 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Підказка для головного пароля" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Налаштування" }, @@ -628,7 +634,7 @@ "message": "Потрібний код підтвердження." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Автентифікацію було скасовано або вона тривала надто довго. Повторіть спробу." }, "invalidVerificationCode": { "message": "Недійсний код підтвердження" @@ -792,6 +798,18 @@ "loginExpired": { "message": "Тривалість вашого сеансу завершилась." }, + "restartRegistration": { + "message": "Перезапустити реєстрацію" + }, + "expiredLink": { + "message": "Протерміноване посилання" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Перезапустіть реєстрацію або спробуйте ввійти." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Можливо, ви вже зареєстровані" + }, "logOutConfirmation": { "message": "Ви дійсно хочете вийти?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Ваш новий головний пароль не задовольняє вимоги політики." }, - "receiveMarketingEmails": { - "message": "Отримуйте електронні листи від Bitwarden з оголошеннями, порадами та інформацією про нові можливості." + "receiveMarketingEmailsV2": { + "message": "Отримуйте поради, оголошення та можливості дослідження від Bitwarden у своїй поштовій скриньці." }, "unsubscribe": { "message": "Відписатися" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Час очікування сховища перевищує обмеження, встановлені вашою організацією." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Автоматичне подання запиту" }, @@ -2782,7 +2803,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Помилка під'єднання до служби Duo. Скористайтеся іншим способом двоетапної перевірки або зверніться до служби підтримки Duo по допомогу." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Запустіть Duo і виконайте дії для завершення входу." @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "Неправильний пароль файлу. Використайте пароль, який ви вводили під час створення експортованого файлу." }, - "importDestination": { - "message": "Призначення імпорту" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Дізнайтеся про параметри імпорту" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index 7f3ad1b0299..880c311f121 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -61,7 +61,7 @@ } }, "moveToOrgDesc": { - "message": "Chọn một tổ chức mà bạn muốn chuyển mục này tới. Việc di chuyển đến một tổ chức sẽ chuyển quyền sở hữu của mục sang tổ chức mà bạn chọn. Bạn sẽ không còn là chủ sở hữu trực tiếp của mục này một khi nó đã được chuyển." + "message": "Chọn một tổ chức mà bạn muốn chuyển mục này đến. Việc chuyển đến một tổ chức sẽ chuyển quyền sở hữu mục này cho tổ chức đó. Bạn sẽ không còn là chủ sở hữu trực tiếp của mục này khi đã chuyển." }, "attachments": { "message": "Tệp đính kèm" @@ -73,7 +73,7 @@ "message": "Tên mục" }, "uri": { - "message": "URL" + "message": "Đường dẫn" }, "uriPosition": { "message": "URL $POSITION$", @@ -123,16 +123,16 @@ "description": "Copy value to clipboard" }, "minimizeOnCopyToClipboard": { - "message": "Thu nhỏ sau khi sao chép vào bộ nhớ đệm" + "message": "Thu nhỏ sau khi sao chép vào khay nhớ tạm" }, "minimizeOnCopyToClipboardDesc": { - "message": "Thu nhỏ sau khi sao chép thông tin của một mục vào bộ nhớ đệm." + "message": "Thu nhỏ ứng dụng sau khi sao chép thông tin của một mục vào khay nhớ tạm." }, "toggleVisibility": { "message": "Bật/tắt khả năng hiển thị" }, "toggleCollapse": { - "message": "Toggle Collapse", + "message": "Bật/tắt thu gọn", "description": "Toggling an expand/collapse state." }, "cardholderName": { @@ -151,7 +151,7 @@ "message": "Mã bảo mật" }, "identityName": { - "message": "Tên đầy đủ" + "message": "Tên danh tính" }, "company": { "message": "Công ty" @@ -181,7 +181,7 @@ "message": "Cần là thành viên cao cấp để sử dụng tính năng này." }, "errorOccurred": { - "message": "Đã xảy ra lỗi chưa xác định." + "message": "Đã xảy ra lỗi." }, "error": { "message": "Lỗi" @@ -245,7 +245,7 @@ "message": "Tiến sĩ" }, "expirationMonth": { - "message": "Tháng Hết Hạn" + "message": "Tháng hết hạn" }, "expirationYear": { "message": "Năm hết hạn" @@ -352,7 +352,7 @@ "message": "Đã thêm mục" }, "editedItem": { - "message": "Mục được chỉnh sửa" + "message": "Đã lưu mục" }, "deleteItem": { "message": "Xóa mục" @@ -361,13 +361,13 @@ "message": "Xóa thư mục" }, "deleteAttachment": { - "message": "Gỡ bỏ tập tin đính kèm" + "message": "Xoá tệp đính kèm" }, "deleteItemConfirmation": { - "message": "Bạn có chắc bạn muốn xóa mục này?" + "message": "Bạn có chắc muốn cho vào thùng rác?" }, "deletedItem": { - "message": "Đã xóa mục" + "message": "Mục đã được cho vào thùng rác" }, "overwritePasswordConfirmation": { "message": "Bạn có chắc chắn muốn ghi đè mật khẩu hiện tại không?" @@ -376,10 +376,10 @@ "message": "Ghi đè tên người dùng" }, "overwriteUsernameConfirmation": { - "message": "Bạn có chắc là muốn ghi đè tên người dùng hiện tại không?" + "message": "Bạn có chắc muốn ghi đè lên tên người dùng hiện tại không?" }, "noneFolder": { - "message": "Không được phân loại", + "message": "Chưa phân loại", "description": "This is the folder for uncategorized items" }, "addFolder": { @@ -419,10 +419,10 @@ "message": "Ký tự đặc biệt (!@#$%^&*)" }, "numWords": { - "message": "Number of Words" + "message": "Số lượng chữ" }, "wordSeparator": { - "message": "Word Separator" + "message": "Dấu tách từ" }, "capitalize": { "message": "Viết hoa", @@ -435,14 +435,14 @@ "message": "Đóng" }, "minNumbers": { - "message": "Số kí tự tối thiểu" + "message": "Số chữ số" }, "minSpecial": { - "message": "Số kí tự đặc biệt tối thiểu", + "message": "Số kí tự đặc biệt", "description": "Minimum Special Characters" }, "ambiguous": { - "message": "Tránh các ký tự không rõ ràng" + "message": "Tránh các ký tự dễ gây nhầm lẫn" }, "searchCollection": { "message": "Tìm kiếm bộ sưu tập" @@ -482,7 +482,7 @@ "message": "Cần di chuyển khóa mã hóa. Vui lòng đăng nhập trang web Bitwaden để cập nhật khóa mã hóa của bạn." }, "editedFolder": { - "message": "Đã chỉnh sửa thư mục" + "message": "Đã lưu thư mục" }, "addedFolder": { "message": "Đã thêm thư mục" @@ -497,13 +497,13 @@ "message": "Đăng nhập hoặc tạo tài khoản mới để truy cập kho mật khẩu của bạn." }, "createAccount": { - "message": "Tạo Tài Khoản" + "message": "Tạo tài khoản" }, "setAStrongPassword": { "message": "Đặt mật khẩu mạnh" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Hoàn thành việc tạo tài khoản của bạn bằng cách đặt mật khẩu" }, "logIn": { "message": "Đăng Nhập" @@ -515,7 +515,7 @@ "message": "Mật khẩu chính" }, "masterPassDesc": { - "message": "Mật khẩu chính là mật khẩu bạn sử dụng để truy cập kho mật khẩu của bạn. Nó rất quan trọng nên bạn không được quên mật khẩu chính của mình. Không có cách nào để khôi phục lại mật khẩu chính nếu bạn quên nó." + "message": "Mật khẩu chính là mật khẩu bạn sử dụng để truy cập kho mật khẩu của bạn. Nó rất quan trọng vì sẽ không có cách nào để lấy lại mật khẩu nếu bạn quên." }, "masterPassHintDesc": { "message": "Một gợi ý mật khẩu có thể giúp bạn nhớ lại mật khẩu chính của bạn nếu bạn quên nó." @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Gợi ý mật khẩu chính" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Cài đặt" }, @@ -604,10 +610,10 @@ "message": "Một lỗi bất ngờ đã xảy ra." }, "itemInformation": { - "message": "Mục thông tin" + "message": "Thông tin mục" }, "noItemsInList": { - "message": "Không có mục nào để liệt kê." + "message": "Không có mục nào." }, "sendVerificationCode": { "message": "Gửi mã xác minh đến email của bạn" @@ -619,25 +625,25 @@ "message": "Đã gửi mã" }, "verificationCode": { - "message": "Mã xác nhận" + "message": "Mã xác minh" }, "confirmIdentity": { - "message": "Xác minh danh tính của bạn để tiếp tục." + "message": "Xác minh danh tính để tiếp tục." }, "verificationCodeRequired": { - "message": "Yêu cầu mã xác nhận." + "message": "Yêu cầu mã xác minh." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Quá trình xác thực đã bị hủy hoặc mất quá nhiều thời gian. Vui lòng thử lại." }, "invalidVerificationCode": { - "message": "Mã xác minh không hợp lệ" + "message": "Mã xác minh không đúng" }, "continue": { "message": "Tiếp tục" }, "enterVerificationCodeApp": { - "message": "Nhập mã xác nhận 6 chữ số từ ứng dụng xác thực của bạn." + "message": "Nhập mã xác minh 6 chữ số từ ứng dụng xác thực của bạn." }, "enterVerificationCodeEmail": { "message": "Nhập mã xác nhận 6 chữ số đã được gửi tới $EMAIL$.", @@ -661,49 +667,49 @@ "message": "Ghi nhớ đăng nhập" }, "sendVerificationCodeEmailAgain": { - "message": "Gửi lại email chứa mã xác nhận" + "message": "Gửi lại email chứa mã xác minh" }, "useAnotherTwoStepMethod": { - "message": "Sử dụng phương pháp xác thực hai lớp khác" + "message": "Sử dụng phương pháp xác minh hai lớp khác" }, "insertYubiKey": { - "message": "Lắp YubiKey vào cổng USB máy tính của bạn, sau đó chạm vào nút trên nó." + "message": "Cắm YubiKey vào cổng USB trên máy tính bạn và bấm nút trên Yubikey." }, "insertU2f": { "message": "Lắp khóa bảo mật vào cổng USB của máy tính. Nếu nó có một nút, nhấn vào nó." }, "recoveryCodeDesc": { - "message": "Bạn mất quyền truy cập vào tất cả các dịch vụ xác thực 2 lớp? Sử dụng mã phục hồi của bạn để vô hiệu hóa tất cả các dịch vụ xác thực hai lớp trong tài khoản của bạn." + "message": "Bạn mất quyền truy cập vào tất cả các dịch vụ xác thực hai bước? Sử dụng mã phục hồi của bạn để vô hiệu hóa tất cả các dịch vụ xác thực hai bước trong tài khoản của bạn." }, "recoveryCodeTitle": { "message": "Mã phục hồi" }, "authenticatorAppTitle": { - "message": "Ứng dụng xác thực" + "message": "Ứng dụng Authenticator" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Nhập mã được tạo bởi ứng dụng xác thực như Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Khóa bảo mật YubiKey OTP" + "message": "Khóa bảo mật OTP Yubico" }, "yubiKeyDesc": { - "message": "Sử dụng YubiKey để truy cập tài khoản của bạn. Làm việc với thiết bị YubiKey 4, 4 Nano, 4C và NEO." + "message": "Sử dụng YubiKey để truy cập tài khoản của bạn. Hoạt động với thiết bị YubiKey 4, 4 Nano, 4C và NEO." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Nhập mã được tạo bởi Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { - "message": "Verify with Duo Security for your organization using the Duo Mobile app, SMS, phone call, or U2F security key.", + "message": "Xác minh với Duo Security cho tổ chức của bạn sử dụng ứng dụng Duo Mobile, SMS, cuộc gọi điện thoại, hoặc khoá bảo mật U2F.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "webAuthnTitle": { "message": "FIDO2 WebAuthn" }, "webAuthnDesc": { - "message": "Sử dụng bất kỳ khoá bảo mật được kích hoạt WebAuthn nào để truy cập tài khoản của bạn." + "message": "Sử dụng bất kỳ khóa bảo mật nào tương thích với WebAuthn để truy cập tài khoản của bạn." }, "emailTitle": { "message": "Email" @@ -712,37 +718,37 @@ "message": "Nhập mã được gửi về email của bạn." }, "loginUnavailable": { - "message": "Đăng nhập không sẵn có" + "message": "Đăng nhập không được" }, "noTwoStepProviders": { - "message": "Tài khoản này đã kích hoạt xác thực hai lớp, tuy nhiên, thiết bị này không hỗ trợ cấu hình dịch vụ xác thực hai lớp đang sử dụng." + "message": "Tài khoản này đã thiết lập xác minh hai bước. Tuy nhiên, thiết bị này không hỗ trợ dịch vụ xác minh hai bước đang sử dụng." }, "noTwoStepProviders2": { "message": "Vui lòng thêm các nhà cung cấp khác được hỗ trợ tốt hơn trên các thiết bị (chẳng hạn như một ứng dụng xác thực)." }, "twoStepOptions": { - "message": "Tùy chọn xác thực hai lớp" + "message": "Tùy chọn xác minh hai bước" }, "selfHostedEnvironment": { - "message": "Môi trường độc lập" + "message": "Môi trường tự lưu trữ" }, "selfHostedEnvironmentFooter": { - "message": "Chỉ định liên kết cơ bản của cài đặt Bitwarden tại chỗ của bạn." + "message": "Chỉ định địa chỉ cơ sở của bản cài đặt Bitwarden được lưu trữ tại máy chủ của bạn." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Nhập địa chỉ cơ sở của bản cài đặt Bitwarden được lưu trữ tại máy chủ của bạn. Ví dụ: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Đối với cấu hình nâng cao. Bạn có thể chỉ định địa chỉ cơ sở của mỗi dịch vụ một cách độc lập." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Bạn phải thêm địa chỉ máy chủ cơ sở hoặc ít nhất một môi trường tùy chỉnh." }, "customEnvironment": { "message": "Môi trường tùy chỉnh" }, "customEnvironmentFooter": { - "message": "Đối với người dùng nâng cao. Bạn có thể chỉ định liên kết cơ bản của mỗi dịch vụ một cách độc lập." + "message": "Đối với người dùng nâng cao. Bạn có thể chỉ định địa chỉ cơ sở của mỗi dịch vụ một cách độc lập." }, "baseUrl": { "message": "Địa chỉ máy chủ" @@ -751,16 +757,16 @@ "message": "Địa chỉ API máy chủ" }, "webVaultUrl": { - "message": "Địa chỉ máy chủ kho web" + "message": "Địa chỉ máy chủ lưu trữ web" }, "identityUrl": { "message": "Địa chỉ nhận dạng máy chủ" }, "notificationsUrl": { - "message": "Notifications Server URL" + "message": "Địa chỉ máy chủ thông báo" }, "iconsUrl": { - "message": "Biểu tượng địa chỉ máy chủ" + "message": "Địa chỉ biểu tượng máy chủ" }, "environmentSaved": { "message": "Địa chỉ môi trường đã được lưu." @@ -792,6 +798,18 @@ "loginExpired": { "message": "Phiên đăng nhập của bạn đã hết hạn." }, + "restartRegistration": { + "message": "Tiến hành đăng ký lại" + }, + "expiredLink": { + "message": "Liên kết đã hết hạn" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Vui lòng đăng ký lại hoặc thử đăng nhập." + }, + "youMayAlreadyHaveAnAccount": { + "message": "Bạn có thể đã có tài khoản" + }, "logOutConfirmation": { "message": "Bạn có chắc chắn muốn đăng xuất không?" }, @@ -799,13 +817,13 @@ "message": "Đăng xuất" }, "addNewLogin": { - "message": "Thêm đăng nhập mới" + "message": "Đăng nhập mới" }, "addNewItem": { - "message": "Thêm mục mới" + "message": "Mục mới" }, "addNewFolder": { - "message": "Thêm thư mục mới" + "message": "Thư mục mới" }, "view": { "message": "Xem" @@ -820,7 +838,7 @@ "message": "Khóa kho" }, "passwordGenerator": { - "message": "Tạo mật khẩu" + "message": "Trình tạo mật khẩu" }, "contactUs": { "message": "Liên hệ với chúng tôi" @@ -838,10 +856,10 @@ "message": "Blog" }, "followUs": { - "message": "Theo chúng tôi" + "message": "Theo dõi chúng tôi" }, "syncVault": { - "message": "Đồng bộ Kho mật khẩu" + "message": "Đồng bộ kho" }, "changeMasterPass": { "message": "Thay đổi mật khẩu chính" @@ -853,7 +871,7 @@ "message": "Bạn có thể thay đổi mật khẩu chính của mình trên Bitwarden bản web." }, "fingerprintPhrase": { - "message": "Fingerprint Phrase", + "message": "Cụm từ mật khẩu", "description": "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." }, "yourAccountsFingerprint": { @@ -861,7 +879,7 @@ "description": "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." }, "goToWebVault": { - "message": "Đi đến bitwarden nền Web" + "message": "Đi đến Bitwarden bản web" }, "getMobileApp": { "message": "Tải ứng dụng điện thoại" @@ -876,7 +894,7 @@ "message": "Đồng bộ thất bại" }, "yourVaultIsLocked": { - "message": "Kho mật khẩu đã bị khóa. Xác minh mật khẩu chính của bạn để mở." + "message": "Kho của bạn đã bị khoá. Hãy xác minh danh tính để tiếp tục." }, "unlock": { "message": "Mở khóa" @@ -898,13 +916,13 @@ "message": "Mật khẩu chính không hợp lệ" }, "twoStepLoginConfirmation": { - "message": "Xác thực hai lớp giúp cho tài khoản của bạn an toàn hơn bằng cách yêu cầu bạn xác minh thông tin đăng nhập của bạn bằng một thiết bị khác như khóa bảo mật, ứng dụng xác thực, SMS, cuộc gọi điện thoại hoặc email. Bạn có thể bật xác thực hai lớp trong kho bitwarden nền web. Bạn có muốn ghé thăm trang web bây giờ?" + "message": "Xác minh 2 bước giúp tài khoản của bạn an toàn hơn bằng cách yêu cầu bạn xác minh bằng một thiết bị khác như khóa bảo mật, ứng dụng xác thực, SMS, cuộc gọi điện thoại hoặc email. Xác minh 2 bước có thể được thiết lập trên bitwarden.com. Bạn có muốn truy cập trang web bây giờ không?" }, "twoStepLogin": { - "message": "Xác thực hai lớp" + "message": "Xác minh hai bước" }, "vaultTimeout": { - "message": "Thời Gian Chờ Của Kho" + "message": "Thời gian mở kho" }, "vaultTimeoutDesc": { "message": "Chọn khi nào thì kho của bạn sẽ hết thời gian chờ và thực hiện hành động đã được chọn." @@ -961,45 +979,45 @@ "message": "Bảo mật" }, "clearClipboard": { - "message": "Dọn dẹp khay nhớ tạm", + "message": "Xóa khay nhớ tạm", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "clearClipboardDesc": { - "message": "Tự động dọn dẹp giá trị được sao chép khỏi khay nhớ tạm của bạn.", + "message": "Tự động xóa mọi thứ đã sao chép khỏi khay nhớ tạm.", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "enableFavicon": { "message": "Hiện biểu tượng trang web" }, "faviconDesc": { - "message": "Hiện một ảnh nhận dạng bên cạnh mỗi lần đăng nhập." + "message": "Hiện logo trang web bên cạnh mỗi đăng nhập." }, "enableMinToTray": { - "message": "Minimize to Tray Icon" + "message": "Thu nhỏ vào khay hệ thống" }, "enableMinToTrayDesc": { - "message": "When minimizing the window, show an icon in the system tray instead." + "message": "Khi thu nhỏ cửa sổ, thay vào đó sẽ hiện một biểu tượng trên khay hệ thống." }, "enableMinToMenuBar": { - "message": "Thu nhỏ về thanh menu" + "message": "Thu nhỏ vào thanh menu" }, "enableMinToMenuBarDesc": { "message": "Khi thu nhỏ sổ, thay vào đó sẽ hiện một biểu tượng trên thanh menu." }, "enableCloseToTray": { - "message": "Close to Tray Icon" + "message": "Đóng vào khay hệ thống" }, "enableCloseToTrayDesc": { "message": "Khi đóng cửa sổ, thay vào đó sẽ hiện một biểu tượng trên khay hệ thống." }, "enableCloseToMenuBar": { - "message": "Đóng thanh menu" + "message": "Đóng vào thanh menu" }, "enableCloseToMenuBarDesc": { "message": "Khi đóng cửa sổ, thay vào đó sẽ hiện một biểu tượng trên thanh menu." }, "enableTray": { - "message": "Enable Tray Icon" + "message": "Hiện biểu tượng khay hệ thống" }, "enableTrayDesc": { "message": "Luôn hiện biểu tượng trên khay hệ thống." @@ -1011,22 +1029,22 @@ "message": "Khi ứng dụng mới mở, chỉ hiện biểu tượng trên khay hệ thống." }, "startToMenuBar": { - "message": "Start to menu bar" + "message": "Khởi động vào thanh menu" }, "startToMenuBarDesc": { - "message": "When the application is first started, only show an icon in the menu bar." + "message": "Khi ứng dụng mới mở, chỉ hiện biểu tượng trên thanh menu." }, "openAtLogin": { - "message": "Tự động bắt đầu khi đăng nhập" + "message": "Khởi động cùng lúc với máy tính" }, "openAtLoginDesc": { - "message": "Tự động chạy ứng dụng máy tính Bitwarden khi đăng nhập." + "message": "Tự động khởi động ứng dụng Bitwarden trên máy tính khi đăng nhập." }, "alwaysShowDock": { "message": "Luôn hiện ở thanh Dock" }, "alwaysShowDockDesc": { - "message": "Hiện biểu tượng Bitwarden trong Dock ngày cả khi thu nhỏ về thanh hệ thống." + "message": "Hiện biểu tượng Bitwarden trong Dock ngay cả khi thu nhỏ về thanh menu." }, "confirmTrayTitle": { "message": "Xác nhận ẩn khay" @@ -1104,7 +1122,7 @@ "message": "Không xác định" }, "copyUsername": { - "message": "Sao chép Tên đăng nhập" + "message": "Sao chép tên đăng nhập" }, "copyNumber": { "message": "Chép số", @@ -1136,13 +1154,13 @@ "message": "1GB bộ nhớ lưu trữ tập tin được mã hóa." }, "premiumSignUpTwoStepOptions": { - "message": "Proprietary two-step login options such as YubiKey and Duo." + "message": "Các tùy chọn xác minh hai bước như YubiKey và Duo." }, "premiumSignUpReports": { "message": "Thanh lọc mật khẩu, kiểm tra an toàn tài khoản và các báo cáo rò rĩ dữ liệu là để giữ cho kho của bạn an toàn." }, "premiumSignUpTotp": { - "message": "Mã xác nhận TOTP (2FA) để đăng nhập vào kho mật khẩu của bạn." + "message": "Mã xác nhận TOTP (2FA) để đăng nhập vào kho của bạn." }, "premiumSignUpSupport": { "message": "Hỗ trợ khách hàng ưu tiên." @@ -1175,14 +1193,14 @@ "message": "Làm mới hoàn tất" }, "passwordHistory": { - "message": "Lịch sử Mật khẩu" + "message": "Lịch sử mật khẩu" }, "clear": { "message": "Xoá", "description": "To clear something out. example: To clear browser history." }, "noPasswordsInList": { - "message": "Không có mật khẩu để liệt kê." + "message": "Chưa có mật khẩu." }, "undo": { "message": "Hoàn tác" @@ -1259,10 +1277,10 @@ } }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Lỗi làm mới khoá truy cập" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Bạn có thể đã bị đăng xuất. Vui lòng đăng xuất và đăng nhập lại." }, "help": { "message": "Trợ giúp" @@ -1274,7 +1292,7 @@ "message": "Kiểm tra xem mật khẩu có bị lộ không." }, "passwordExposed": { - "message": "Mật khẩu này đã bị lộ $VALUE$ thời gian trong các dữ liệu vi phạm. Bạn nên thay đổi nó.", + "message": "Mật khẩu này đã bị lộ $VALUE$ lần trong các vụ rò rỉ dữ liệu. Bạn nên đổi nó.", "placeholders": { "value": { "content": "$1", @@ -1283,7 +1301,7 @@ } }, "passwordSafe": { - "message": "Mật khẩu này không được tìm thấy trong bất kỳ dữ liệu vi phạm nào được biết đến. Nó an toàn để sử dụng." + "message": "Mật khẩu này không tìm thấy trong bất kỳ vụ rò rỉ dữ liệu nào. Nó an toàn để sử dụng." }, "baseDomain": { "message": "Tên miền cơ sở", @@ -1319,7 +1337,7 @@ "message": "Bật/tắt tùy chọn" }, "organization": { - "message": "Organization", + "message": "Tổ chức", "description": "An entity of multiple related people (ex. a team or business organization)." }, "default": { @@ -1329,18 +1347,18 @@ "message": "Thoát ra" }, "showHide": { - "message": "Show / Hide", + "message": "Hiển thị / Ẩn", "description": "Text for a button that toggles the visibility of the window. Shows the window when it is hidden or hides the window if it is currently open." }, "hideToTray": { - "message": "Hide to Tray" + "message": "Ẩn xuống khay hệ thống" }, "alwaysOnTop": { "message": "Luôn trên cùng", "description": "Application window should always stay on top of other windows" }, "dateUpdated": { - "message": "Ngày cập nhật", + "message": "Cập nhật vào", "description": "ex. Date this item was updated" }, "dateCreated": { @@ -1348,103 +1366,103 @@ "description": "ex. Date this item was created" }, "datePasswordUpdated": { - "message": "Password Updated", + "message": "Đã cập nhật mật khẩu", "description": "ex. Date this password was updated" }, "exportFrom": { "message": "Xuất từ" }, "exportVault": { - "message": "Export Vault" + "message": "Xuất kho" }, "fileFormat": { - "message": "File Format" + "message": "Định dạng tệp tin" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "Tập tin này sẽ được bảo vệ bằng mật khẩu và yêu cầu mật khẩu để giải mã." }, "filePassword": { "message": "Mật khẩu tập tin" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "message": "Mật khẩu này sẽ được sử dụng để xuất và nhập tập tin này" }, "accountRestrictedOptionDescription": { - "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account." + "message": "Sử dụng khóa mã hóa tài khoản của bạn, được tạo từ tên người dùng và mật khẩu chính của bạn để mã hóa tệp xuất và giới hạn việc nhập chỉ cho tài khoản Bitwarden hiện tại." }, "passwordProtected": { "message": "Mật khẩu đã được bảo vệ" }, "passwordProtectedOptionDescription": { - "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." + "message": "Thiết lập mật khẩu cho tệp để mã hóa dữ liệu xuất và nhập nó vào bất kỳ tài khoản Bitwarden nào bằng cách sử dụng mật khẩu đó để giải mã." }, "exportTypeHeading": { - "message": "Export type" + "message": "Loại xuất" }, "accountRestricted": { "message": "Tài khoản bị hạn chế" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "“Mật khẩu tập tin” và “Nhập lại mật khẩu tập tin” không khớp." }, "hCaptchaUrl": { - "message": "Url hCaptcha", + "message": "Địa chỉ hCaptcha", "description": "hCaptcha is the name of a website, should not be translated" }, "loadAccessibilityCookie": { - "message": "Tải cookie hỗ trợ tiếp cận" + "message": "Tải cookie trợ năng" }, "registerAccessibilityUser": { - "message": "Register as an accessibility user at", + "message": "Đăng ký như người dùng trợ năng tại", "description": "ex. Register as an accessibility user at hcaptcha.com" }, "copyPasteLink": { - "message": "Copy and paste the link sent to your email below" + "message": "Sao chép và dán liên kết được gửi tới email của bạn bên dưới" }, "enterhCaptchaUrl": { - "message": "Enter URL to load accessibility cookie for hCaptcha", + "message": "Nhập địa chỉ để tải cookie trợ năng cho hCaptcha", "description": "hCaptcha is the name of a website, should not be translated" }, "hCaptchaUrlRequired": { - "message": "hCaptcha Url is required", + "message": "Địa chỉ hCaptcha là bắt buộc", "description": "hCaptcha is the name of a website, should not be translated" }, "invalidUrl": { - "message": "Url không hợp lệ" + "message": "Địa chỉ không hợp lệ" }, "done": { "message": "Xong" }, "accessibilityCookieSaved": { - "message": "Accessibility cookie saved!" + "message": "Đã lưu cookie trợ năng!" }, "noAccessibilityCookieSaved": { - "message": "Không có cookie hỗ trợ tương tác nào được lưu" + "message": "Không có cookie trợ năng nào được lưu" }, "warning": { "message": "CẢNH BÁO", "description": "WARNING (should stay in capitalized letters if the language permits)" }, "confirmVaultExport": { - "message": "Xác nhận xuất kho lưu trữ" + "message": "Xác nhận xuất kho" }, "exportWarningDesc": { - "message": "This export contains your vault data in an unencrypted format. You should not store or send the exported file over unsecure channels (such as email). Delete it immediately after you are done using it." + "message": "Bản xuất này chứa dữ liệu kho bạn và không được mã hóa. Bạn không nên lưu trữ hay gửi tập tin đã xuất thông qua phương thức rủi ro (như email). Vui lòng xóa nó ngay lập tức khi bạn đã sử dụng xong." }, "encExportKeyWarningDesc": { - "message": "File xuất mã hóa dữ liệu xủa bạn bằng khóa giải mã. Nếu bạn thay đổi khóa giải mã, bạn nên xuất file lại vì bạn sẽ không thể giải mã file này." + "message": "Quá trình xuất này mã hóa dữ liệu của bạn bằng khóa mã hóa của tài khoản. Nếu bạn đã từng thay đổi khóa mã hóa của tài khoản, bạn cần xuất lại vì bạn sẽ không thể giải mã tệp xuất này." }, "encExportAccountWarningDesc": { - "message": "Account encryption keys are unique to each Bitwarden user account, so you can't import an encrypted export into a different account." + "message": "Khóa mã hóa tài khoản là duy nhất cho mỗi tài khoản Bitwarden, vì vậy bạn không thể nhập tệp xuất được mã hóa vào một tài khoản khác." }, "noOrganizationsList": { - "message": "You do not belong to any organizations. Organizations allow you to securely share items with other users." + "message": "Bạn chưa thuộc tổ chức nào. Tổ chức sẽ cho phép bạn chia sẻ các mục với người dùng khác một cách bảo mật." }, "noCollectionsInList": { - "message": "Không có bộ sưu tập nào để liệt kê." + "message": "Không có bộ sưu tập nào." }, "ownership": { - "message": "Quyền sở hữu" + "message": "Sở hữu" }, "whoOwnsThisItem": { "message": "Ai sở hữu mục này?" @@ -1462,7 +1480,7 @@ "description": "ex. A weak password. Scale: Weak -> Good -> Strong" }, "weakMasterPassword": { - "message": "Weak Master Password" + "message": "Mật khẩu chính Yếu" }, "weakMasterPasswordDesc": { "message": "Mật khẩu chính bạn vừa chọn có vẻ yếu. Bạn nên chọn mật khẩu chính (hoặc cụm từ mật khẩu) mạnh để bảo vệ đúng cách tài khoản Bitwarden của bạn. Bạn có thực sự muốn dùng mật khẩu chính này?" @@ -1490,7 +1508,7 @@ "message": "Mở khóa với Windows Hello" }, "additionalWindowsHelloSettings": { - "message": "Additional Windows Hello settings" + "message": "Cài đặt Windows Hello bổ sung" }, "windowsHelloConsentMessage": { "message": "Xác minh cho Bitwarden." @@ -1499,10 +1517,10 @@ "message": "Mở khóa với Touch ID" }, "additionalTouchIdSettings": { - "message": "Additional Touch ID settings" + "message": "Cài đặt Touch ID bổ sung" }, "touchIdConsentMessage": { - "message": "Xác minh cho Bitwarden." + "message": "mở khoá kho của bạn" }, "autoPromptWindowsHello": { "message": "Yêu cầu xác minh Windows Hello khi mở" @@ -1511,10 +1529,10 @@ "message": "Yêu cầu xác minh Touch ID khi mở" }, "requirePasswordOnStart": { - "message": "Require password or PIN on app start" + "message": "Yêu cầu mật khẩu hoặc mã PIN khi mở" }, "recommendedForSecurity": { - "message": "Recommended for security." + "message": "Đề xuất để tăng cường bảo mật." }, "lockWithMasterPassOnRestart": { "message": "Khóa với mật khẩu chính khi khởi động lại" @@ -1538,7 +1556,7 @@ "message": "Tuỳ chỉnh" }, "enableMenuBar": { - "message": "Bật biểu tượng thanh menu" + "message": "Hiển thị biểu tượng thanh menu" }, "enableMenuBarDesc": { "message": "Luôn hiển biểu tượng trên thanh menu." @@ -1578,10 +1596,10 @@ "message": "Tạo bản sao" }, "passwordGeneratorPolicyInEffect": { - "message": "Có một hoặc vài chính sách của tổ chức đang làm ảnh hưởng đến cài đặt tạo mật khẩu của bạn." + "message": "Các chính sách của tổ chức đang ảnh hưởng đến cài đặt tạo mật khẩu của bạn." }, "vaultTimeoutAction": { - "message": "Hành Động Khi Hết Thời Gian Chờ" + "message": "Khi hết thời gian mở kho" }, "vaultTimeoutActionLockDesc": { "message": "Kho bị khóa sẽ yêu cầu bạn nhập lại mật khẩu chính để có thể truy cập." @@ -1590,7 +1608,7 @@ "message": "Kho bị đăng xuất sẽ yêu cầu bạn xác thực lại để có thể truy cập." }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Set up an unlock method to change your vault timeout action." + "message": "Thiết lập khóa khi hết thời gian chờ kho." }, "lock": { "message": "Khóa", @@ -1601,7 +1619,7 @@ "description": "Noun: a special folder to hold deleted items" }, "searchTrash": { - "message": "Tìm kiếm thùng rác" + "message": "Tìm kiếm trong thùng rác" }, "permanentlyDeleteItem": { "message": "Xoá vĩnh viễn mục" @@ -1616,10 +1634,10 @@ "message": "Mục đã được khôi phục" }, "permanentlyDelete": { - "message": "Xóa Vĩnh Viễn" + "message": "Xoá vĩnh viễn" }, "vaultTimeoutLogOutConfirmation": { - "message": "Đăng xuất sẽ xóa tất các truy cập vào kho của bạn và yêu cầu xác thực trực tuyến sau khi khoảng thời gian chờ hết. Bạn có chắc bạn muốn dùng cài đặt này?" + "message": "Tuỳ chọn đăng xuất sẽ đăng xuất khỏi kho sau khi hết thời gian mở kho và bạn sẽ cần đăng nhập lại để tiếp tục sử dụng. Bạn có chắc muốn sử dụng tuỳ chọn này không?" }, "vaultTimeoutLogOutConfirmationTitle": { "message": "Xác nhận hành động khi hết thời gian chờ" @@ -1631,11 +1649,11 @@ "message": "Thiết lập mật khẩu chính" }, "orgPermissionsUpdatedMustSetPassword": { - "message": "Your organization permissions were updated, requiring you to set a master password.", + "message": "Quyền tổ chức của bạn đã được cập nhật, yêu cầu bạn đặt mật khẩu chính.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "orgRequiresYouToSetPassword": { - "message": "Your organization requires you to set a master password.", + "message": "Tổ chức của bạn yêu cầu bạn đặt mật khẩu chính.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { @@ -1652,7 +1670,7 @@ "message": "Xác nhận mật khẩu chính mới" }, "masterPasswordPolicyInEffect": { - "message": "One or more organization policies require your master password to meet the following requirements:" + "message": "Các chính sách của tổ chức yêu cầu mật khẩu chính của bạn phải:" }, "policyInEffectMinComplexity": { "message": "Độ mạnh tối thiểu $SCORE$", @@ -1676,7 +1694,7 @@ "message": "Có chứa một hay nhiều ký tự viết hoa" }, "policyInEffectLowercase": { - "message": "Chứa một hoặc nhiều kí tự viết thường" + "message": "Có chứa một hay nhiều ký tự thường" }, "policyInEffectNumbers": { "message": "Có chứa một hay nhiều số" @@ -1691,19 +1709,19 @@ } }, "masterPasswordPolicyRequirementsNotMet": { - "message": "Your new master password does not meet the policy requirements." + "message": "Mật khẩu chính bạn chọn không đáp ứng yêu cầu." }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Nhận lời khuyên, thông báo và cơ hội nghiên cứu từ Bitwarden trong hộp thư đến của bạn." }, "unsubscribe": { "message": "Huỷ đăng ký" }, "atAnyTime": { - "message": "at any time." + "message": "bất cứ lúc nào." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Bằng cách tiếp tục, bạn đồng ý" }, "and": { "message": "và" @@ -1718,7 +1736,7 @@ "message": "Cho phép tích hợp với trình duyệt" }, "enableBrowserIntegrationDesc": { - "message": "Used for biometrics in browser." + "message": "Sử dụng để xác thực sinh trắc học trên trình duyệt." }, "enableDuckDuckGoBrowserIntegration": { "message": "Cho phép tích hợp trình duyệt DuckDuckGo" @@ -1727,13 +1745,13 @@ "message": "Sử dụng kho Bitwarden của bạn khi tìm kiếm bằng DuckDuckGo." }, "browserIntegrationUnsupportedTitle": { - "message": "Không hỗ trợ tích hợp trình duyệt" + "message": "Tích hợp trình duyệt không được hỗ trợ" }, "browserIntegrationErrorTitle": { - "message": "Error enabling browser integration" + "message": "Lỗi khi bật tích hợp trình duyệt" }, "browserIntegrationErrorDesc": { - "message": "An error has occurred while enabling browser integration." + "message": "Đã xảy ra lỗi khi bật tích hợp với trình duyệt." }, "browserIntegrationMasOnlyDesc": { "message": "Rất tiếc, tính năng tích hợp trình duyệt hiện chỉ được hỗ trợ trong phiên bản App Store trên Mac." @@ -1748,7 +1766,7 @@ "message": "Yêu cầu xác minh để tích hợp trình duyệt" }, "enableBrowserIntegrationFingerprintDesc": { - "message": "Add an additional layer of security by requiring fingerprint phrase confirmation when establishing a link between your desktop and browser. This requires user action and verification each time a connection is created." + "message": "Tăng cường bảo mật bằng cách yêu cầu xác nhận cụm từ mật khẩu khi kết nối máy tính với trình duyệt. Việc này yêu cầu bạn phải thực hiện thao tác xác minh mỗi khi tạo kết nối mới." }, "enableHardwareAcceleration": { "message": "Dùng tính năng tăng tốc phần cứng" @@ -1757,16 +1775,16 @@ "message": "Mặc định cài đặt này được bật. Chỉ tắt khi gặp sự cố đồ họa. Cần khởi động lại." }, "approve": { - "message": "Chấp nhận" + "message": "Phê duyệt" }, "verifyBrowserTitle": { "message": "Xác minh kết nối trình duyệt" }, "verifyBrowserDesc": { - "message": "Please ensure the shown fingerprint is identical to the fingerprint showed in the browser extension." + "message": "Vui lòng đảm bảo dấu vân tay hiển thị giống hệt với dấu vân tay được hiển thị trong tiện ích mở rộng trình duyệt." }, "verifyNativeMessagingConnectionTitle": { - "message": "$APPID$ wants to connect to Bitwarden", + "message": "$APPID$ muốn kết nối với Bitwarden", "placeholders": { "appid": { "content": "$1", @@ -1784,19 +1802,19 @@ "message": "Sinh trắc học chưa được thiết lập" }, "biometricsNotEnabledDesc": { - "message": "Browser biometrics requires desktop biometrics to be set up in the settings first." + "message": "Sinh trắc học trên trình duyệt yêu cầu sinh trắc học trên máy tính phải được cài đặt trước." }, "personalOwnershipSubmitError": { - "message": "Due to an enterprise policy, you are restricted from saving items to your individual vault. Change the ownership option to an organization and choose from available collections." + "message": "Do chính sách doanh nghiệp, bạn bị hạn chế lưu các mục vào kho cá nhân của mình. Thay đổi tùy chọn quyền sở hữu thành một tổ chức và chọn từ các bộ sưu tập có sẵn." }, "hintEqualsPassword": { "message": "Gợi ý mật khẩu không được trùng với mật khẩu của bạn." }, "personalOwnershipPolicyInEffect": { - "message": "An organization policy is affecting your ownership options." + "message": "Chính sách của tổ chức đang ảnh hưởng đến các tùy chọn quyền sở hữu của bạn." }, "personalOwnershipPolicyInEffectImports": { - "message": "An organization policy has blocked importing items into your individual vault." + "message": "Chính sách của tổ chức đã chặn việc nhập các mục vào kho cá nhân của bạn." }, "allSends": { "message": "Tất cả mục Gửi", @@ -1830,7 +1848,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { - "message": "Ngày Hết Hạn" + "message": "Ngày hết hạn" }, "expirationDateDesc": { "message": "Nếu được thiết lập, mục Gửi này sẽ hết hạn vào ngày và giờ được chỉ định.", @@ -1920,11 +1938,11 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copySendLinkToClipboard": { - "message": "Sao chép liên kết tới Khay nhớ tạm", + "message": "Sao chép liên kết tới khay nhớ tạm", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copySendLinkOnSave": { - "message": "Sao chép liên kết chia sẻ của mục Gửi này tới bộ nhớ tạm khi lưu." + "message": "Sao chép liên kết chia sẻ của mục Gửi này tới khay nhớ tạm khi lưu." }, "sendDisabled": { "message": "Đã loại bỏ Gửi", @@ -1968,10 +1986,10 @@ "message": "Các chính sách của tổ chức đang ảnh hưởng đến tùy chọn Gửi của bạn." }, "emailVerificationRequired": { - "message": "Yêu cầu xác nhận danh tính qua Email" + "message": "Yêu cầu xác nhận danh tính qua email" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "Email đã xác minh" }, "emailVerificationRequiredDesc": { "message": "Bạn phải xác minh email của mình để sử dụng tính năng này." @@ -1995,13 +2013,13 @@ "message": "Mật khẩu chính của bạn gần đây đã được thay đổi bởi một quản trị viên trong tổ chức của bạn. Để truy cập Kho, bạn phải cập nhật nó ngay bây giờ. Tiếp tục sẽ đăng xuất bạn khỏi phiên hiện tại của bạn, yêu cầu bạn đăng nhập lại. Các phiên hoạt động trên các thiết bị khác có thể tiếp tục hoạt động trong tối đa một giờ." }, "updateWeakMasterPasswordWarning": { - "message": "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "Mật khẩu chính của bạn không đáp ứng chính sách tổ chức của bạn. Để truy cập kho, bạn phải cập nhật mật khẩu chính của mình ngay bây giờ. Việc tiếp tục sẽ đăng xuất bạn khỏi phiên hiện tại và bắt buộc đăng nhập lại. Các phiên hoạt động trên các thiết bị khác có thể tiếp tục duy trì hoạt động trong tối đa một giờ." }, "tryAgain": { "message": "Thử lại" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Cần xác minh cho thao tác này. Hãy đặt mã PIN để tiếp tục." }, "setPin": { "message": "Thiết lập mã PIN" @@ -2013,10 +2031,10 @@ "message": "Đang chờ xác nhận" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Không thể hoàn tất sinh trắc học." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Cần một phương pháp khác?" }, "useMasterPassword": { "message": "Dùng mật khẩu chính" @@ -2040,7 +2058,7 @@ "message": "Phút" }, "vaultTimeoutPolicyInEffect": { - "message": "Chính sách tổ chức của bạn đang ảnh hưởng đến thời gian chờ Kho của bạn. Thời gian chờ kho tối đa được phép là $HOURS$ giờ và $MINUTES$ phút", + "message": "Tổ chức của bạn đã đặt thời gian mở kho tối đa là $HOURS$ giờ và $MINUTES$ phút.", "placeholders": { "hours": { "content": "$1", @@ -2079,7 +2097,10 @@ } }, "vaultTimeoutTooLarge": { - "message": "Thời gian chờ Kho của bạn vượt quá các hạn chế do tổ chức của bạn đặt ra." + "message": "Thời gian mở kho vượt quá giới hạn do tổ chức của bạn đặt ra." + }, + "inviteAccepted": { + "message": "Invitation accepted" }, "resetPasswordPolicyAutoEnroll": { "message": "Đăng ký tự động" @@ -2088,10 +2109,10 @@ "message": "Tổ chức này có chính sách doanh nghiệp sẽ tự động đặt lại mật khẩu chính cho bạn. Đăng ký sẽ cho phép quản trị viên tổ chức thay đổi mật khẩu chính của bạn." }, "vaultExportDisabled": { - "message": "Vault export removed" + "message": "Đã xoá xuất kho" }, "personalVaultExportPolicyInEffect": { - "message": "One or more organization policies prevents you from exporting your personal vault." + "message": "Các chính sách của tổ chức ngăn cản bạn xuất kho lưu trữ cá nhân của mình." }, "addAccount": { "message": "Thêm tài khoản" @@ -2103,7 +2124,7 @@ "message": "Đã xóa mật khẩu chính" }, "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", + "message": "$ORGANIZATION$ đang sử dụng SSO với khóa máy chủ tự lưu trữ. Các thành viên của tổ chức này không cần mật khẩu chính để đăng nhập.", "placeholders": { "organization": { "content": "$1", @@ -2115,19 +2136,19 @@ "message": "Rời khỏi tổ chức" }, "leaveOrganizationConfirmation": { - "message": "Are you sure you want to leave this organization?" + "message": "Bạn có chắc chắn muốn rời tổ chức này không?" }, "leftOrganization": { "message": "Bạn đã rời khỏi tổ chức." }, "ssoKeyConnectorError": { - "message": "Key connector error: make sure key connector is available and working correctly." + "message": "Lỗi kết nối khóa: hãy đảm bảo kết nối khóa khả dụng và hoạt động chính xác." }, "lockAllVaults": { - "message": "Khoá tất cả kho lưu trữ" + "message": "Khoá tất cả kho" }, "accountLimitReached": { - "message": "No more than 5 accounts may be logged in at the same time." + "message": "Bạn chỉ có thể đăng nhập tối đa 5 tài khoản cùng lúc." }, "accountPreferences": { "message": "Tuỳ chỉnh" @@ -2136,10 +2157,10 @@ "message": "Cài đặt ứng dụng (tất cả tài khoản)" }, "accountSwitcherLimitReached": { - "message": "Account limit reached. Log out of an account to add another." + "message": "Số lượng tài khoản đã đạt giới hạn. Đăng xuất khỏi một tài khoản để thêm tài khoản khác." }, "settingsTitle": { - "message": "App settings for $EMAIL$", + "message": "Cài đặt ứng dụng cho $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -2157,13 +2178,13 @@ "message": "Tùy chọn" }, "sessionTimeout": { - "message": "Your session has timed out. Please go back and try logging in again." + "message": "Phiên đăng nhập của bạn đã hết hạn. Vui lòng quay trở lại và thử đăng nhập lại." }, "exportingPersonalVaultTitle": { - "message": "Exporting individual vault" + "message": "Đang xuất dữ liệu kho cá nhân" }, "exportingIndividualVaultDescription": { - "message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.", + "message": "Chỉ dữ liệu trong kho cá nhân liên kết với $EMAIL$ mới được xuất. Không bao gồm \ncác dữ liệu trong kho tổ chức. Chỉ thông tin mục kho mới được xuất, sẽ không có các tệp đính kèm.", "placeholders": { "email": { "content": "$1", @@ -2172,10 +2193,10 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "Đang xuất dữ liệu kho tổ chức" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "Chỉ dữ liệu trong kho tổ chức $ORGANIZATION$ mới được xuất. Các kho cá nhân hoặc của tổ chức khác sẽ không được bao gồm.", "placeholders": { "organization": { "content": "$1", @@ -2190,7 +2211,7 @@ "message": "Đã mở khóa" }, "generator": { - "message": "Tạo" + "message": "Trình tạo" }, "whatWouldYouLikeToGenerate": { "message": "Bạn muốn tạo gì?" @@ -2212,13 +2233,13 @@ "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "Use your email provider's sub-addressing capabilities." + "message": "Sử dụng khả năng địa chỉ phụ của nhà cung cấp dịch vụ mail của bạn." }, "catchallEmail": { "message": "Catch-all email" }, "catchallEmailDesc": { - "message": "Use your domain's configured catch-all inbox." + "message": "Sử dụng hộp thư bạn đã thiết lập để nhận tất cả email gửi đến tên miền của bạn." }, "random": { "message": "Ngẫu nhiên" @@ -2248,7 +2269,7 @@ "message": "Tạo bí danh email với dịch vụ chuyển tiếp bên ngoài." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "Lỗi $SERVICENAME$: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -2262,11 +2283,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Được tạo bởi Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Trang web: $WEBSITE$. Được tạo bởi Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -2276,7 +2297,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Khoá API $SERVICENAME$ không hợp lệ", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2286,7 +2307,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Khoá API $SERVICENAME$ không hợp lệ: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2300,7 +2321,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "Không thể lấy ID tài khoản email ẩn từ $SERVICENAME$.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2310,7 +2331,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Tên miền $SERVICENAME$ không hợp lệ.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -2320,7 +2341,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Địa chỉ $SERVICENAME$ không hợp lệ.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -2330,7 +2351,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "$SERVICENAME$ đã xảy ra lỗi không xác định.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -2340,7 +2361,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "Người chuyển tiếp không xác định: '$SERVICENAME$'.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -2354,7 +2375,7 @@ "description": "Part of a URL." }, "apiAccessToken": { - "message": "API Access Token" + "message": "Khoá truy cập API" }, "apiKey": { "message": "Khóa API" @@ -2363,13 +2384,13 @@ "message": "Yêu cầu đăng ký gói Premium" }, "organizationIsDisabled": { - "message": "Organization suspended" + "message": "Tổ chức đã ngưng hoạt động" }, "disabledOrganizationFilterError": { - "message": "Items in suspended organizations cannot be accessed. Contact your organization owner for assistance." + "message": "Không thể truy cập các mục trong tổ chức đã ngưng hoạt động. Hãy liên hệ với chủ sở hữu tổ chức để được hỗ trợ." }, "neverLockWarning": { - "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." + "message": "Bạn có chắc chắn muốn chọn \"Không bao giờ\" không? Lựa chọn này sẽ lưu khóa mã hóa kho của bạn trực tiếp trên thiết bị. Hãy nhớ bảo vệ thiết bị của bạn thật cẩn thận nếu bạn chọn tùy chọn này." }, "vault": { "message": "Kho mật khẩu" @@ -2378,7 +2399,7 @@ "message": "Đăng nhập bằng mật khẩu chính" }, "loggingInAs": { - "message": "Logging in as" + "message": "Đang đăng nhập như" }, "rememberEmail": { "message": "Ghi nhớ email" @@ -2402,16 +2423,16 @@ "message": "Đăng nhập bằng thiết bị khác" }, "loginInitiated": { - "message": "Login initiated" + "message": "Bắt đầu đăng nhập" }, "notificationSentDevice": { "message": "Một thông báo đã được gửi đến thiết bị của bạn." }, "fingerprintMatchInfo": { - "message": "Please make sure your vault is unlocked and Fingerprint phrase matches the other device." + "message": "Vui lòng đảm bảo rằng bạn đã mở khoá kho và cụm từ mật khẩu khớp trên thiết bị khác." }, "fingerprintPhraseHeader": { - "message": "Fingerprint phrase" + "message": "Cụm từ mật khẩu" }, "needAnotherOption": { "message": "Đăng nhập bằng thiết bị phải được thiết lập trong cài đặt của ứng dụng Bitwarden. Dùng cách khác?" @@ -2430,7 +2451,7 @@ "message": "Bạn đang cố đăng nhập?" }, "logInAttemptBy": { - "message": "Login attempt by $EMAIL$", + "message": "Nỗ lực đăng nhập bằng $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -2500,7 +2521,7 @@ "message": "Yêu cầu đăng nhập" }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Đang tạo tài khoản trên" }, "checkYourEmail": { "message": "Kiểm tra email của bạn" @@ -2539,16 +2560,16 @@ "message": "Quan trọng:" }, "accessTokenUnableToBeDecrypted": { - "message": "You have been logged out because your access token could not be decrypted. Please log in again to resolve this issue." + "message": "Bạn đã bị đăng xuất do khoá truy cập của bạn không thể giải mã. Vui lòng đăng nhập lại để khắc phục sự cố này." }, "refreshTokenSecureStorageRetrievalFailure": { - "message": "You have been logged out because your refresh token could not be retrieved. Please log in again to resolve this issue." + "message": "Bạn đã bị đăng xuất do khoá truy cập của bạn không thể truy xuất. Vui lòng đăng nhập lại để khắc phục sự cố này." }, "masterPasswordHint": { "message": "Mật khẩu chính của bạn không thể phục hồi nếu bạn quên nó!" }, "characterMinimum": { - "message": "$LENGTH$ character minimum", + "message": "Tối thiểu $LENGTH$ ký tự", "placeholders": { "length": { "content": "$1", @@ -2557,13 +2578,13 @@ } }, "windowsBiometricUpdateWarning": { - "message": "Bitwarden recommends updating your biometric settings to require your master password (or PIN) on the first unlock. Would you like to update your settings now?" + "message": "Bitwarden khuyên bạn nên cập nhật cài đặt sinh trắc học để yêu cầu mật khẩu chính (hoặc mã PIN) trong lần mở khóa đầu tiên. Bạn có muốn cập nhật cài đặt của mình bây giờ không?" }, "windowsBiometricUpdateWarningTitle": { - "message": "Recommended Settings Update" + "message": "Cập nhật cài đặt được đề xuất" }, "deviceApprovalRequired": { - "message": "Device approval required. Select an approval option below:" + "message": "Yêu cầu phê duyệt thiết bị. Chọn một tuỳ chọn phê duyệt bên dưới:" }, "rememberThisDevice": { "message": "Lưu thiết bị này" @@ -2591,19 +2612,19 @@ "description": "European Union" }, "loggingInOn": { - "message": "Logging in on" + "message": "Đang đăng nhập vào" }, "selfHostedServer": { "message": "tự lưu trữ" }, "accessDenied": { - "message": "Access denied. You do not have permission to view this page." + "message": "Truy cập bị từ chối. Bạn không có quyền xem trang này." }, "accountSuccessfullyCreated": { "message": "Tạo tài khoản thành công!" }, "adminApprovalRequested": { - "message": "Admin approval requested" + "message": "Yêu cầu quản trị viên phê duyệt" }, "adminApprovalRequestSentToAdmins": { "message": "Yêu cầu của bạn đã được gửi đến quản trị viên." @@ -2624,7 +2645,7 @@ "message": "Thiết bị tin cậy" }, "inputRequired": { - "message": "Không được để trống." + "message": "Trường này là bắt buộc." }, "required": { "message": "bắt buộc" @@ -2633,7 +2654,7 @@ "message": "Tìm kiếm" }, "inputMinLength": { - "message": "Input must be at least $COUNT$ characters long.", + "message": "Giá trị nhập vào phải ít nhất $COUNT$ ký tự.", "placeholders": { "count": { "content": "$1", @@ -2642,7 +2663,7 @@ } }, "inputMaxLength": { - "message": "Input must not exceed $COUNT$ characters in length.", + "message": "Giá trị nhập vào không được vượt quá $COUNT$ ký tự.", "placeholders": { "count": { "content": "$1", @@ -2651,7 +2672,7 @@ } }, "inputForbiddenCharacters": { - "message": "The following characters are not allowed: $CHARACTERS$", + "message": "Các ký tự sau không được phép sử dụng: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -2660,7 +2681,7 @@ } }, "inputMinValue": { - "message": "Input value must be at least $MIN$.", + "message": "Giá trị nhập vào phải ít nhất $MIN$.", "placeholders": { "min": { "content": "$1", @@ -2669,7 +2690,7 @@ } }, "inputMaxValue": { - "message": "Input value must not exceed $MAX$.", + "message": "Giá trị nhập vào không được vượt quá $MAX$.", "placeholders": { "max": { "content": "$1", @@ -2678,17 +2699,17 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "Có ít nhất 1 địa chỉ email không hợp lệ" }, "inputTrimValidator": { - "message": "Input must not contain only whitespace.", + "message": "Giá trị nhập vào không được chỉ có khoảng trắng.", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "Input is not an email address." + "message": "Giá trị nhập vào không phải là địa chỉ email." }, "fieldsNeedAttention": { - "message": "$COUNT$ field(s) above need your attention.", + "message": "Có $COUNT$ trường cần bạn xem xét ở trên.", "placeholders": { "count": { "content": "$1", @@ -2703,7 +2724,7 @@ "message": "-- Nhập để lọc --" }, "multiSelectLoading": { - "message": "Retrieving options..." + "message": "Đang tải các tuỳ chọn..." }, "multiSelectNotFound": { "message": "Không tìm thấy mục nào" @@ -2712,7 +2733,7 @@ "message": "Xoá tất cả" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ $QUANTITY$ nhiều hơn", "placeholders": { "quantity": { "content": "$1", @@ -2721,25 +2742,25 @@ } }, "submenu": { - "message": "Submenu" + "message": "Menu con" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Ẩn/hiện thanh điều hướng bên" }, "skipToContent": { - "message": "Skip to content" + "message": "Chuyển đến nội dung" }, "typePasskey": { - "message": "Passkey" + "message": "Mã khoá" }, "passkeyNotCopied": { - "message": "Không thể sao chép passkey" + "message": "Không thể sao chép mã khoá" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "Bản sao sẽ không bao gồm mã khoá. Bạn có muốn tiếp tục tạo bản sao mục này?" }, "aliasDomain": { - "message": "Alias domain" + "message": "Tên miền thay thế" }, "importData": { "message": "Nhập dữ liệu", @@ -2749,10 +2770,10 @@ "message": "Lỗi nhập" }, "importErrorDesc": { - "message": "There was a problem with the data you tried to import. Please resolve the errors listed below in your source file and try again." + "message": "Có vấn đề với dữ liệu bạn cố gắng nhập. Vui lòng khắc phục các lỗi được liệt kê bên dưới trong tệp nguồn của bạn và thử lại." }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "Giải quyết các lỗi bên dưới và thử lại." }, "description": { "message": "Mô tả" @@ -2773,7 +2794,7 @@ "message": "Tổng" }, "importWarning": { - "message": "You are importing data to $ORGANIZATION$. Your data may be shared with members of this organization. Do you want to proceed?", + "message": "Bạn đang nhập dữ liệu vào $ORGANIZATION$. Dữ liệu của bạn có thể được chia sẻ với các thành viên của tổ chức này. Bạn có muốn tiếp tục không?", "placeholders": { "organization": { "content": "$1", @@ -2782,31 +2803,31 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Lỗi kết nối với dịch vụ Duo. Sử dụng phương thức đăng nhập hai bước khác hoặc liên hệ với Duo để được hỗ trợ." }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Khởi chạy Duo và làm theo các bước để hoàn tất đăng nhập." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Tài khoản của bạn yêu cầu xác minh hai bước với Duo." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Khởi chạy Duo trong trình duyệt" }, "importFormatError": { - "message": "Dữ liệu không được định dạng đúng cách, vui lòng kiểm tra và thử lại." + "message": "Dữ liệu không được định dạng đúng. Vui lòng kiểm tra tập tin nhập và thử lại." }, "importNothingError": { - "message": "Chưa nhập gì." + "message": "Không có gì được nhập." }, "importEncKeyError": { - "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." + "message": "Lỗi giải mã tập tin đã xuất. Khóa mã hóa của bạn không khớp với khóa mã hóa được sử dụng để xuất dữ liệu." }, "invalidFilePassword": { - "message": "Invalid file password, please use the password you entered when you created the export file." + "message": "Mật khẩu tập tin không hợp lệ, vui lòng sử dụng mật khẩu bạn đã nhập khi xuất tập tin." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Đến" }, "learnAboutImportOptions": { "message": "Tìm hiểu các tuỳ chọn nhập của bạn" @@ -2818,7 +2839,7 @@ "message": "Chọn bộ sưu tập" }, "importTargetHint": { - "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", + "message": "Chọn tùy chọn này để di chuyển nội dung tập tin đã được nhập đến $DESTINATION$", "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": { @@ -2828,10 +2849,10 @@ } }, "importUnassignedItemsError": { - "message": "File contains unassigned items." + "message": "Tập tin chứa các mục không xác định." }, "selectFormat": { - "message": "Select the format of the import file" + "message": "Chọn định dạng tập tin nhập" }, "selectImportFile": { "message": "Chọn tập tin nhập" @@ -2856,7 +2877,7 @@ } }, "confirmVaultImport": { - "message": "Xác nhận nhập kho lưu trữ" + "message": "Xác nhận nhập kho" }, "confirmVaultImportDesc": { "message": "Tập tin này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu để nhập dữ liệu." @@ -2868,10 +2889,10 @@ "message": "Đã xuất dữ liệu kho của bạn" }, "multifactorAuthenticationCancelled": { - "message": "Multifactor authentication cancelled" + "message": "Đã hủy xác thực đa yếu tố" }, "noLastPassDataFound": { - "message": "No LastPass data found" + "message": "Không tìm thấy dữ liệu LastPass" }, "incorrectUsernameOrPassword": { "message": "Tên người dùng hoặc mật khẩu không đúng" @@ -2886,59 +2907,59 @@ "message": "Mã PIN không đúng" }, "multifactorAuthenticationFailed": { - "message": "Multifactor authentication failed" + "message": "Xác thực đa yếu tố thất bại" }, "includeSharedFolders": { - "message": "Include shared folders" + "message": "Bao gồm các thư mục được chia sẻ" }, "lastPassEmail": { - "message": "LastPass Email" + "message": "Email LastPass" }, "importingYourAccount": { - "message": "Importing your account..." + "message": "Đang nhập tài khoản của bạn..." }, "lastPassMFARequired": { - "message": "LastPass multifactor authentication required" + "message": "Yêu cầu xác thực đa yếu tố LastPass" }, "lastPassMFADesc": { - "message": "Enter your one-time passcode from your authentication app" + "message": "Nhập mã OTP từ ứng dụng xác thực của bạn" }, "lastPassOOBDesc": { - "message": "Approve the login request in your authentication app or enter a one-time passcode." + "message": "Phê duyệt yêu cầu đăng nhập trên ứng dụng xác thực của bạn hoặc nhập mã OTP." }, "passcode": { - "message": "Passcode" + "message": "Mật mã" }, "lastPassMasterPassword": { - "message": "LastPass master password" + "message": "Mật khẩu chính LastPass" }, "lastPassAuthRequired": { - "message": "LastPass authentication required" + "message": "Yêu cầu xác thực LastPass" }, "awaitingSSO": { - "message": "Awaiting SSO authentication" + "message": "Đang chờ xác thực SSO" }, "awaitingSSODesc": { - "message": "Please continue to log in using your company credentials." + "message": "Vui lòng tiếp tục đăng nhập bằng thông tin đăng nhập của công ty bạn." }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "Xem hướng dẫn chi tiết trên trang trợ giúp của chúng tôi tại", "description": "This is followed a by a hyperlink to the help website." }, "importDirectlyFromLastPass": { - "message": "Import directly from LastPass" + "message": "Nhập trực tiếp từ LastPass" }, "importFromCSV": { "message": "Nhập từ CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Try again or look for an email from LastPass to verify it's you." + "message": "Thử lại hoặc tìm email từ LastPass để xác minh đó là bạn." }, "collection": { "message": "Bộ Sưu Tập" }, "lastPassYubikeyDesc": { - "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." + "message": "Cắm khóa YubiKey được liên kết với tài khoản LastPass của bạn vào cổng USB của máy tính, sau đó nhấn nút trên YubiKey." }, "commonImportFormats": { "message": "Định dạng chung", @@ -2957,16 +2978,16 @@ "message": "Kích hoạt tính năng tăng tốc phần cứng và khởi động lại" }, "removePasskey": { - "message": "Xóa passkey" + "message": "Xóa mã khoá" }, "passkeyRemoved": { - "message": "Đã xóa passkey" + "message": "Đã xóa mã khoá" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Lỗi khi gán vào bộ sưu tập chỉ định." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Lỗi khi gán vào thư mục chỉ định." }, "viewItemsIn": { "message": "Xem các mục trong $NAME$", @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Dữ liệu" } } diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index cbceb244caf..099a9b24665 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "主密码提示" }, + "joinOrganization": { + "message": "加入组织" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "通过设置主密码完成加入此组织。" + }, "settings": { "message": "设置" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "您的登录会话已过期。" }, + "restartRegistration": { + "message": "重新开始注册" + }, + "expiredLink": { + "message": "失效链接" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "请重新注册或尝试登录。" + }, + "youMayAlreadyHaveAnAccount": { + "message": "您可能已经有一个账户了" + }, "logOutConfirmation": { "message": "确定要注销吗?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "您的新主密码不符合策略要求。" }, - "receiveMarketingEmails": { - "message": "接收来自 Bitwarden 的电子邮件,以获取公告、建议和调研。" + "receiveMarketingEmailsV2": { + "message": "获取来自 Bitwarden 的建议、公告和调研电子邮件。" }, "unsubscribe": { "message": "取消订阅" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "您的密码库超时时间超出了组织设置的限制。" }, + "inviteAccepted": { + "message": "邀请已接受" + }, "resetPasswordPolicyAutoEnroll": { "message": "自动注册" }, @@ -2500,7 +2521,7 @@ "message": "已请求登录" }, "creatingAccountOn": { - "message": "创建账户于" + "message": "正创建账户于" }, "checkYourEmail": { "message": "检查您的电子邮箱" @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "无效的文件密码,请使用您创建导出文件时输入的密码。" }, - "importDestination": { - "message": "导入目的地" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "了解您的导入选项" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index 9d18a6ba15c..33d7acd2340 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "設定" }, @@ -792,6 +798,18 @@ "loginExpired": { "message": "您的登入會話已過期。" }, + "restartRegistration": { + "message": "Restart registration" + }, + "expiredLink": { + "message": "Expired link" + }, + "pleaseRestartRegistrationOrTryLoggingIn": { + "message": "Please restart registration or try logging in." + }, + "youMayAlreadyHaveAnAccount": { + "message": "You may already have an account" + }, "logOutConfirmation": { "message": "您確定要登出嗎?" }, @@ -1693,8 +1711,8 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "新的主密碼不符合原則要求。" }, - "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "receiveMarketingEmailsV2": { + "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." }, "unsubscribe": { "message": "Unsubscribe" @@ -2081,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "您的密碼庫逾時時間超過組織設定的限制。" }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "自動註冊" }, @@ -2805,8 +2826,8 @@ "invalidFilePassword": { "message": "檔案密碼無效,請使用您當初匯出檔案時輸入的密碼。" }, - "importDestination": { - "message": "匯入目的地" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "瞭解更多匯入選項" @@ -3001,5 +3022,8 @@ "example": "Work" } } + }, + "data": { + "message": "Data" } } From f96a66ebd99fba7085c18e00b978b7b8bfecef0c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:48:01 +0000 Subject: [PATCH 11/46] Autosync the updated translations (#10280) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 213 +++- apps/browser/src/_locales/az/messages.json | 221 +++- apps/browser/src/_locales/be/messages.json | 209 +++- apps/browser/src/_locales/bg/messages.json | 243 +++- apps/browser/src/_locales/bn/messages.json | 225 +++- apps/browser/src/_locales/bs/messages.json | 231 +++- apps/browser/src/_locales/ca/messages.json | 209 +++- apps/browser/src/_locales/cs/messages.json | 227 +++- apps/browser/src/_locales/cy/messages.json | 259 +++- apps/browser/src/_locales/da/messages.json | 219 +++- apps/browser/src/_locales/de/messages.json | 223 +++- apps/browser/src/_locales/el/messages.json | 519 +++++--- apps/browser/src/_locales/en_GB/messages.json | 207 +++- apps/browser/src/_locales/en_IN/messages.json | 207 +++- apps/browser/src/_locales/es/messages.json | 209 +++- apps/browser/src/_locales/et/messages.json | 209 +++- apps/browser/src/_locales/eu/messages.json | 219 +++- apps/browser/src/_locales/fa/messages.json | 221 +++- apps/browser/src/_locales/fi/messages.json | 281 ++++- apps/browser/src/_locales/fil/messages.json | 209 +++- apps/browser/src/_locales/fr/messages.json | 233 +++- apps/browser/src/_locales/gl/messages.json | 229 +++- apps/browser/src/_locales/he/messages.json | 221 +++- apps/browser/src/_locales/hi/messages.json | 217 +++- apps/browser/src/_locales/hr/messages.json | 209 +++- apps/browser/src/_locales/hu/messages.json | 221 +++- apps/browser/src/_locales/id/messages.json | 219 +++- apps/browser/src/_locales/it/messages.json | 209 +++- apps/browser/src/_locales/ja/messages.json | 243 +++- apps/browser/src/_locales/ka/messages.json | 229 +++- apps/browser/src/_locales/km/messages.json | 231 +++- apps/browser/src/_locales/kn/messages.json | 219 +++- apps/browser/src/_locales/ko/messages.json | 213 +++- apps/browser/src/_locales/lt/messages.json | 213 +++- apps/browser/src/_locales/lv/messages.json | 209 +++- apps/browser/src/_locales/ml/messages.json | 225 +++- apps/browser/src/_locales/mr/messages.json | 229 +++- apps/browser/src/_locales/my/messages.json | 231 +++- apps/browser/src/_locales/nb/messages.json | 209 +++- apps/browser/src/_locales/ne/messages.json | 231 +++- apps/browser/src/_locales/nl/messages.json | 219 +++- apps/browser/src/_locales/nn/messages.json | 231 +++- apps/browser/src/_locales/or/messages.json | 231 +++- apps/browser/src/_locales/pl/messages.json | 205 +++- apps/browser/src/_locales/pt_BR/messages.json | 297 ++++- apps/browser/src/_locales/pt_PT/messages.json | 219 +++- apps/browser/src/_locales/ro/messages.json | 209 +++- apps/browser/src/_locales/ru/messages.json | 219 +++- apps/browser/src/_locales/si/messages.json | 219 +++- apps/browser/src/_locales/sk/messages.json | 203 +++- apps/browser/src/_locales/sl/messages.json | 209 +++- apps/browser/src/_locales/sr/messages.json | 241 +++- apps/browser/src/_locales/sv/messages.json | 217 +++- apps/browser/src/_locales/te/messages.json | 231 +++- apps/browser/src/_locales/th/messages.json | 227 +++- apps/browser/src/_locales/tr/messages.json | 267 ++++- apps/browser/src/_locales/uk/messages.json | 293 ++++- apps/browser/src/_locales/vi/messages.json | 1051 ++++++++++------- apps/browser/src/_locales/zh_CN/messages.json | 261 +++- apps/browser/src/_locales/zh_TW/messages.json | 213 +++- apps/browser/store/locales/el/copy.resx | 4 +- 61 files changed, 12643 insertions(+), 2023 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 40bd4c91ab5..c11b241f80b 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "قم بالتسجيل أو إنشاء حساب جديد للوصول إلى خزنتك الآمنة." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "إنشاء حساب" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "تلميح كلمة المرور الرئيسية (إختياري)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "علامة تبويب" }, @@ -736,6 +745,10 @@ "newUri": { "message": "رابط جديد" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "تمت إضافة العنصر" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "اطلب إضافة تسجيل الدخول" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "اطلب إضافة عنصر إذا لم يُعثر عليه في خزنتك." }, "addLoginNotificationDescAlt": { "message": "اطلب إضافة عنصر إذا لم يتم العثور على عنصر في المخزن الخاص بك. ينطبق على جميع حسابات تسجيل الدخول." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "أظهر البطاقات في صفحة التبويبات" }, "showCardsCurrentTabDesc": { "message": "قائمة عناصر البطاقة في صفحة التبويب لسهولة التعبئة التلقائية." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "إظهار الهويات على صفحة التبويب" }, @@ -1220,8 +1242,17 @@ "message": "إظهار قائمة الملء التلقائي في حقول النموذج", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "ينطبق على جميع الحسابات المسجل الدخول بها." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "إيقاف تشغيل إعدادات مدير كلمات المرور الافتراضي في متصفحك لتجنب التضارب." @@ -1241,15 +1272,34 @@ "message": "عندما يتم اختيار ايقونة الملء التلقائي", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "ملء تلقائي عند تحميل الصفحة" }, "enableAutoFillOnPageLoadDesc": { "message": "إذا تم اكتشاف نموذج تسجيل الدخول، يتم التعبئة التلقائية عند تحميل صفحة الويب." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "مواقع المساومة أو غير الموثوق بها يمكن أن تستغل الملء التلقائي في تحميل الصفحة." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "تعرف على المزيد حول الملء التلقائي" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "قيمة منطقية" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "مرتبط", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "النطاقات المستبعدة" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ نطاق غير صالح", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "إرسال", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "إعدادات الملء التلقائي" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "ملء تلقائي لاختصار لوحة المفاتيح" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "افتح حسابك لعرض تسجيلات الدخول المطابقة", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "فتح الحساب", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "ملء بيانات الاعتماد لـ", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "إضافة عنصر مخزن جديد", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "تتوفر قائمة الملء التلقائي لBitwarden. اضغط على مفتاح السهم لأسفل للتحديد.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "كلمة مرور الملف غير صالحة، الرجاء استخدام كلمة المرور التي أدخلتها عند إنشاء ملف التصدير." }, - "importDestination": { - "message": "وجهة الاستيراد" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "تعرف على خيارات الاستيراد الخاصة بك" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 068a94864fd..e9b0c46e50e 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Güvənli anbarınıza müraciət etmək üçün giriş edin və ya yeni bir hesab yaradın." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Hesab yarat" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Ana parol ipucu (ixtiyari)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Vərəq" }, @@ -661,19 +670,19 @@ "message": "Giriş seansınızın müddəti bitdi." }, "logIn": { - "message": "Log in" + "message": "Giriş et" }, "restartRegistration": { - "message": "Restart registration" + "message": "Qeydiyyatı yenidən başlat" }, "expiredLink": { - "message": "Expired link" + "message": "Vaxtı bitmiş keçid" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Lütfən qeydiyyatı yenidən başladın və ya giriş etməyə çalışın." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Artıq bir hesabınız ola bilər" }, "logOutConfirmation": { "message": "Çıxış etmək istədiyinizə əminsiniz?" @@ -736,6 +745,10 @@ "newUri": { "message": "Yeni URI" }, + "addDomain": { + "message": "Domen əlavə et", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Element əlavə edildi" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Giriş əlavə etmək üçün soruş" }, + "vaultSaveOptionsTitle": { + "message": "Anbar seçimlərində saxla" + }, "addLoginNotificationDesc": { "message": "Anbarınızda tapılmayan bir elementin əlavə edilməsi soruşulsun." }, "addLoginNotificationDescAlt": { "message": "Anbarınızda tapılmayan bir elementin əlavə edilməsi soruşulsun. Giriş etmiş bütün hesablara aiddir." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Kartları Vərəq səhifəsində göstər" }, "showCardsCurrentTabDesc": { "message": "Asan avto-doldurma üçün Vərəq səhifəsində kart elementlərini sadalayın." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Vərəq səhifəsində kimlikləri göstər" }, @@ -1220,8 +1242,17 @@ "message": "Form xanalarında avto-doldurma menyusunu göstər", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Giriş etmiş bütün hesablara aiddir." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Ziddiyyətləri önləmək üçün brauzerinizin daxili parol meneceri ayarlarını söndürün." @@ -1241,15 +1272,34 @@ "message": "Avto-doldurma ikonu seçiləndə", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Səhifə yüklənəndə avto-doldurmanı fəallaşdır" }, "enableAutoFillOnPageLoadDesc": { "message": "Giriş formu aşkarlananda, səhifə yüklənən zaman formu avto-doldurma icra edilsin." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Təhlükəli və ya güvənilməyən veb saytlar, səhifə yüklənərkən avto-doldurmanı istifadə edə bilər." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Avto-doldurma haqqında daha ətraflı" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Yoxlanış qutusu" + }, "cfTypeLinked": { "message": "Əlaqələndirildi", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Yeni ana parolunuz siyasət tələblərini qarşılamır." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Bitwarden-in tövsiyə, elan və araşdırma imkanlarını gələn qutunuzda əldə edin." }, "unsubscribe": { "message": "Abunəlikdən çıx" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Bir təşkilat siyasəti, elementlərin fərdi anbarınıza köçürülməsini əngəllədi." }, + "domainsTitle": { + "message": "Domenlər", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "İstisna edilən domenlər" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden, giriş etmiş bütün hesablar üçün bu domenlərin giriş detallarını saxlamağı soruşmayacaq. Dəyişikliklərin qüvvəyə minməsi üçün səhifəni təzələməlisiniz." }, + "websiteItemLabel": { + "message": "Veb sayt $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ yararlı bir domen deyil", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "İstisna domen dəyişikliyi saxlanıldı" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Parolla qorunan" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "\"Send\" keçidini kopyala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Avto-doldurma ayarları" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Avto-doldurma klaviatura qısayolu" }, @@ -2970,10 +3048,18 @@ "message": "Uyuşan giriş məlumatlarına baxmaq üçün hesabınızın kilidini açın", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Hesabın kilidini aç", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Kimlik məlumatlarını doldur", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Yeni anbar elementi əlavə et", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden avto-doldurma menyusu mövcuddur. Seçmək üçün aşağı ox düyməsinə basın.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Yararsız fayl parolu, lütfən xaricə köçürmə faylını yaradarkən daxil etdiyiniz parolu istifadə edin." }, - "importDestination": { - "message": "Hədəfi daxilə köçür" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Daxilə köçürmə seçimlərinizi öyrənin" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Ortaq formatlar", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Bitwarden ilkin parol meneceriniz olaraq təyin edilsin?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Kopyalanacaq dəyər yoxdur" }, - "assignCollections": { - "message": "Kolleksiyaları təyin et" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "E-poçtu kopyala" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Giriş məlumatları" }, @@ -3667,11 +3805,17 @@ "loading": { "message": "Yüklənir" }, + "data": { + "message": "Data" + }, "assign": { "message": "Təyin et" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Yalnız bu kolleksiyalara müraciəti olan təşkilat üzvləri bu elementləri görə biləcək." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { "message": "$TOTAL_COUNT$ element seçmisiniz. Düzəliş icazəniz olmadığı üçün $READONLY_COUNT$ elementi güncəlləyə bilməzsiniz.", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Təyin ediləcək kolleksiyaları seçin" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ seçilmiş təşkilata birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$, $ORG$ təşkilatına birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ aşağı daşındı, mövqeyi $INDEX$/$LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 10187da7dd5..4e4240c178c 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Увайдзіце або стварыце новы ўліковы запіс для доступу да бяспечнага сховішча." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Стварыць уліковы запіс" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Падказка да асноўнага пароля (неабавязкова)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Укладка" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Новы URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Элемент дададзены" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Пытацца пры дадаванні лагіна" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Пытацца пра дадаванне элемента, калі ён адсутнічае ў вашым сховішчы." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Паказваць карткі на старонцы з укладкамі" }, "showCardsCurrentTabDesc": { "message": "Спіс элементаў картак на старонцы з укладкамі для лёгкага аўтазапаўнення." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Паказваць пасведчанні на старонцы з укладкамі" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Аўтазапаўненне пры загрузцы старонкі" }, "enableAutoFillOnPageLoadDesc": { "message": "Калі выяўлена форма ўваходу, то будзе выканана яе аўтазапаўненне падчас загрузкі вэб-старонкі." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Скампраметаваныя або ненадзейныя вэб-сайты могуць задзейнічаць функцыю аўтазапаўнення падчас загрузкі старонкі." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Даведацца больш пра аўтазапаўненне" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Булева" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Звязана", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Выключаныя дамены" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ не з'яўляецца правільным даменам", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Абаронена паролем" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Скапіяваць спасылку на Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Налады аўтазапаўнення" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Спалучэнні клавіш аўтазапаўнення" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Даведацца пра параметры імпартавання" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 2379fdb8186..5c0c7b9ed1e 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Впишете се или създайте нов абонамент, за да достъпите защитен трезор." }, + "inviteAccepted": { + "message": "Поканата е приета" + }, "createAccount": { "message": "Създаване на акаунт" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Подсказване за главната парола (по избор)" }, + "joinOrganization": { + "message": "Присъединяване към организацията" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Завършете присъединяването си към тази организация като зададете главна парола." + }, "tab": { "message": "Раздел" }, @@ -640,13 +649,13 @@ "message": "Сканирайте QR-кода за удостоверяване от текущата страница" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Направете 2-стъпковото удостоверяване безпроблемно и незабележимо" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Битуорден може да съхранява и попълва кодовете за 2-стъпково потвърждаване. Копирайте ключа в това поле." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Битуорден може да съхранява и попълва кодовете за 2-стъпково потвърждаване. Изберете иконката с камера, за да направите екранна снимка на QR-кода от този уеб сайт или копирайте ключа в това поле." }, "copyTOTP": { "message": "Копиране на удостоверителния ключ (TOTP)" @@ -661,19 +670,19 @@ "message": "Сесията ви изтече." }, "logIn": { - "message": "Log in" + "message": "Вписване" }, "restartRegistration": { - "message": "Restart registration" + "message": "Рестартиране на регистрацията" }, "expiredLink": { - "message": "Expired link" + "message": "Връзка с изтекла давност" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Рестартирайте регистрацията или опитайте да се впишете." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Може вече да имате регистрация" }, "logOutConfirmation": { "message": "Сигурни ли сте, че искате да се отпишете?" @@ -736,6 +745,10 @@ "newUri": { "message": "Нов унифициран идентификатор на ресурс" }, + "addDomain": { + "message": "Добавяне на домейн", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Елементът е добавен" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Питане за добавяне на запис" }, + "vaultSaveOptionsTitle": { + "message": "Запазване в настройките на трезора" + }, "addLoginNotificationDesc": { "message": "Известията за запазване на регистрации автоматично ви подканят да запазите новите регистрации в трезора при първото ви вписване в тях." }, "addLoginNotificationDescAlt": { "message": "Питане за добавяне на елемент, ако такъв не бъде намерен в трезора. Прилага се за всички регистрации, в които сте вписан(а)." }, + "showCardsInVaultView": { + "message": "Показване на картите като предложения за авт. попълване в изгледа на трезора" + }, "showCardsCurrentTab": { "message": "Показване на карти в страницата с разделите" }, "showCardsCurrentTabDesc": { "message": "Показване на картите в страницата с разделите, за лесно автоматично попълване." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Показване на самоличности в страницата с разделите" }, @@ -1220,7 +1242,16 @@ "message": "Показване на меню за авт. попълване при полетата на формулярите", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Предложения за авт. попълване" + }, + "showInlineMenuLabel": { + "message": "Показване на предложения за авт. попълване на полетата във формуляри" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Показване на предложения когато иконката е избрана" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Прилага се за всички регистрации, в които сте вписан(а)." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Когато бъде избрана иконката за авт. попълване", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Автоматично попълване при зареждане на страницата" + }, "enableAutoFillOnPageLoad": { "message": "Включване на автоматичното попълване" }, "enableAutoFillOnPageLoadDesc": { "message": "При засичане на формуляр за вписване при зареждането на уеб страницата автоматично да се попълват данните на съответстващата регистрация." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Внимание:$CLOSETAG$ Опасните или компроментирани уеб сайтове могат да се възползват от функционалността за автоматично попълване при зареждане на страницата.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Компроментирани и измамни уеб сайтове могат да се възползват от автоматичното попълване при зареждане на страницата." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Научете повече относно рисковете" + }, "learnMoreAboutAutofill": { "message": "Научете повече относно автоматичното попълване" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Булево" }, + "cfTypeCheckbox": { + "message": "Поле за отметка" + }, "cfTypeLinked": { "message": "Свързано", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Паролата ви не отговаря на политиките." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Получавайте съвети, обявления и предложения за участие в проучвания от Битуорден в пощенската си кутия." }, "unsubscribe": { "message": "Отписване" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Политика на организацията забранява да внасяте елементи в личния си трезор." }, + "domainsTitle": { + "message": "Домейни", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Изключени домейни" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Битуорден няма да пита дали да запазва данните за вход в тези сайтове за всички регистрации, в които сте вписан(а). За да влезе правилото в сила, презаредете страницата." }, + "websiteItemLabel": { + "message": "Уеб сайт $number$ (адрес)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ не е валиден домейн", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Промените на изключените домейни са запазени" + }, "send": { "message": "Изпращане", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Защита с парола" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Копиране на връзката към изпратеното", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Настройки за автоматичното попълване" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Клавишна комбинация за авт. попълване" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Промяна на клавишната комбинация" + }, "autofillShortcut": { "message": "Клавишна комбинация за автоматично попълване" }, @@ -2970,10 +3048,18 @@ "message": "Отключете регистрацията си, за да видите съвпадащите записи за вписване", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Отключване на регистрацията", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Попълване на данните за", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Добавяне на нов елемент в трезора", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Има налично меню за авт. попълване на Битуорден. Натиснете стрелката надолу, за да го изберете.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Неправилна парола за файла. Използвайте паролата, която сте въвели при създаването на изнесения файл." }, - "importDestination": { - "message": "Място на внасяне" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Научете повече относно възможностите за внасяне" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Често използвани формати", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Продължаване към настройките на браузъра?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Продължаване към помощния център?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Променете настройките на браузъра си за автоматично попълване и управление на паролите.", + "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": "Можете да прегледате и настроите клавишните комбинации за добавката в настройките на браузъра си.", + "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": "Променете настройките на браузъра си за автоматично попълване и управление на паролите.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Можете да прегледате и настроите клавишните комбинации за добавката в настройките на браузъра си.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Искате ли да направите Битуорден своя управител на пароли по подразбиране?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Няма стойности за копиране" }, - "assignCollections": { - "message": "Свързване на колекции" + "assignToCollections": { + "message": "Свързване с колекции" }, "copyEmail": { "message": "Копиране на е-пощата" @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "Данни за вписване" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Ключ за удостоверяване" }, "cardDetails": { "message": "Данни за картата" @@ -3667,14 +3805,20 @@ "loading": { "message": "Зареждане" }, - "assign": { - "message": "Assign" + "data": { + "message": "Данни" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "assign": { + "message": "Свързване" + }, + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Само членовете на организацията, които имат достъп до тези колекции, ще могат да виждат елемента." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Само членовете на организацията, които имат достъп до тези колекции, ще могат да виждат елементите." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Избрали сте $TOTAL_COUNT$ елемента Не можете да промените $READONLY_COUNT$ от елементите, тъй като нямате право за редактиране.", "placeholders": { "total_count": { "content": "$1", @@ -3769,23 +3913,35 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Изберете колекции за свързване" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 елемент ще бъде преместен завинаги в избраната организация. Вече няма да притежавате този елемент." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ елемента ще бъдат преместени завинаги в избраната организация. Вече няма да притежавате тези елементи.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 елемент ще бъде преместен завинаги в $ORG$. Вече няма да притежавате този елемент.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ елемента ще бъдат преместени завинаги в $ORG$. Вече няма да притежавате тези елементи.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3794,13 +3950,31 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Успешно свързване на колекциите" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Не сте избрали нищо." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Избраните записи бяха преместени в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemsMovedToOrg": { + "message": "Елементите са преместени в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Елементът е преместен в $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Местоположение на елемента" } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index ad80eaf1b04..a03f23f7341 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "আপনার সুরক্ষিত ভল্টে প্রবেশ করতে লগ ইন করুন অথবা একটি নতুন অ্যাকাউন্ট তৈরি করুন।" }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "অ্যাকাউন্ট তৈরি করুন" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "মূল পাসওয়ার্ড ইঙ্গিত (ঐচ্ছিক)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "ট্যাব" }, @@ -736,6 +745,10 @@ "newUri": { "message": "নতুন URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "বস্তু যোগ করা হয়েছে" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "\"লগইন যোগ করুন বিজ্ঞপ্তি\" স্বয়ংক্রিয়ভাবে আপনই যখনই প্রথমবারের জন্য লগ ইন করেন তখন আপনার ভল্টে নতুন লগইনগুলি সংরক্ষণ করতে অনুরোধ জানায়।" }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "পৃষ্ঠা লোডে স্বতঃপূরণ সক্ষম করুন" }, "enableAutoFillOnPageLoadDesc": { "message": "যদি কোনও লগইন ফর্ম সনাক্ত হয়, ওয়েব পৃষ্ঠাটি লোড হওয়ার পরে স্বয়ংক্রিয়ভাবে স্বতঃপূরণ করুন।" }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "ভল্ট পপআপ খুলুন" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "বুলিয়ান" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "পাসওয়ার্ড সুরক্ষিত" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send লিঙ্ক কপি করুন", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index b80f37fabce..c30765cb3d4 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Prijavite se ili napravite novi račun da biste pristupili svom sigurnom trezoru." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Napravi račun" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Copy security code" }, "autoFill": { - "message": "Auto-fill" + "message": "Autofill" }, "autoFillLogin": { "message": "Auto-fill login" @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index ba16faf012c..e13929b40bc 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Inicieu sessió o creeu un compte nou per accedir a la caixa forta." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Crea un compte" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Pista de la contrasenya mestra (opcional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Pestanya" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Nova URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Element afegit" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Demana d'afegir els inicis de sessió" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "La \"Notificació per afegir inicis de sessió\" demana automàticament que guardeu els nous inicis de sessió a la vostra caixa forta quan inicieu la sessió per primera vegada." }, "addLoginNotificationDescAlt": { "message": "Demana afegir un element si no se'n troba cap a la caixa forta. S'aplica a tots els comptes connectats." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Mostra les targetes a la pàgina de pestanya" }, "showCardsCurrentTabDesc": { "message": "Llista els elements de la targeta a la pàgina de pestanya per facilitar l'autoemplenat." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Mostra les identitats a la pàgina de pestanya" }, @@ -1220,8 +1242,17 @@ "message": "Mostra el menú d'emplenament automàtic als camps del formulari", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "S'aplica a tots els comptes connectats." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Desactiveu la configuració integrada del gestor de contrasenyes del vostre navegador per evitar conflictes." @@ -1241,15 +1272,34 @@ "message": "Quan la icona d'emplenament automàtic està seleccionada", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Habilita l'emplenament automàtic en carregar la pàgina" }, "enableAutoFillOnPageLoadDesc": { "message": "Si es detecta un formulari d'inici de sessió, es realitza automàticament un emplenament automàtic quan es carrega la pàgina web." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Els llocs web compromesos o no fiables poden aprofitar-se de l'emplenament automàtic en carregar de la pàgina." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Obteniu més informació sobre l'emplenament automàtic" }, @@ -1257,7 +1307,7 @@ "message": "Configuració per defecte d'emplenament automàtic per als elements d'inici de sessió" }, "defaultAutoFillOnPageLoadDesc": { - "message": "Després d'habilitar l'emplenament automàtic a la càrrega de la pàgina, podeu habilitar o inhabilitar la característica per a elements d'inici de sessió individuals. Aquesta és la configuració per defecte per als elements d'inici de sessió que no estan configurats per separat." + "message": "Podeu desactivar l'emplenament automàtic a la càrrega de la pàgina per a elements d'inici de sessió individuals des de la vista d'edició de l'element." }, "itemAutoFillOnPageLoad": { "message": "Emplenament automàtic a la càrrega de la pàgina (si està habilitat a Opcions)" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Booleà" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Enllaçat", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Una política d'organització ha bloquejat la importació d'elements a la vostra caixa forta individual." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Dominis exclosos" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden no demanarà que es guarden les dades d'inici de sessió d'aquests dominis per a tots els comptes iniciats. Heu d'actualitzar la pàgina perquè els canvis tinguen efecte." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ no és un domini vàlid", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protegit amb contrasenya" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copia l'enllaç Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Configuració d'emplenament automàtic" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Drecera de teclat d'emplenament automàtic" }, @@ -2970,10 +3048,18 @@ "message": "Desbloqueja el compte per veure els inicis de sessió coincidents", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Desbloqueja el compte", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Ompliu les credencials per a", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Afegeix un nou element a la caixa forta", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "El menú d'emplenament automàtic de Bitwarden està disponible. Premeu la tecla de fletxa avall per seleccionar-lo.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "La contrasenya del fitxer no és vàlida. Utilitzeu la contrasenya que vau introduir quan vau crear el fitxer d'exportació." }, - "importDestination": { - "message": "Destinació de la importació" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Obteniu informació sobre les opcions d'importació" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Formats comuns", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Fer que Bitwarden siga el gestor de contrasenyes predeterminat?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index 17e7869fd3a..78be9eed82a 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Pro přístup do Vašeho bezpečného trezoru se přihlaste nebo si vytvořte nový účet." }, + "inviteAccepted": { + "message": "Pozvánka byla přijata" + }, "createAccount": { "message": "Vytvořit účet" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Nápověda k hlavnímu heslu (volitelné)" }, + "joinOrganization": { + "message": "Přidat se k organizaci" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Dokončete připojení k této organizaci nastavením hlavního hesla." + }, "tab": { "message": "Karta" }, @@ -661,19 +670,19 @@ "message": "Platnost přihlášení vypršela." }, "logIn": { - "message": "Log in" + "message": "Přihlásit se" }, "restartRegistration": { - "message": "Restart registration" + "message": "Restartovat registraci" }, "expiredLink": { - "message": "Expired link" + "message": "Platnost odkazu vypršela" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Restartujte registraci nebo se zkuste přihlásit." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Už možná máte účet" }, "logOutConfirmation": { "message": "Opravdu se chcete odhlásit?" @@ -736,6 +745,10 @@ "newUri": { "message": "Nová URI" }, + "addDomain": { + "message": "Přidat doménu", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Položka byla přidána" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ptát se na přidání přihlášení" }, + "vaultSaveOptionsTitle": { + "message": "Uložit do voleb trezoru" + }, "addLoginNotificationDesc": { "message": "Zeptá se na uložení údajů, pokud nebyly v trezoru nalezeny." }, "addLoginNotificationDescAlt": { "message": "Požádá o přidání položky, pokud nebyla nalezena v trezoru. Platí pro všechny přihlášené účty." }, + "showCardsInVaultView": { + "message": "Zobrazit karty jako návrhy automatického vyplňování v zobrazení trezoru" + }, "showCardsCurrentTab": { "message": "Zobrazit platební karty na obrazovce Karta" }, "showCardsCurrentTabDesc": { "message": "Pro snadné vyplnění zobrazí platební karty na obrazovce Karta." }, + "showIdentitiesInVaultView": { + "message": "Zobrazit identity jako návrhy automatického vyplňování v zobrazení trezoru" + }, "showIdentitiesCurrentTab": { "message": "Zobrazit identity na obrazovce Karta" }, @@ -1220,7 +1242,16 @@ "message": "Zobrazit menu automatického vyplňování v polích formuláře", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Návrhy automatického vyplňování" + }, + "showInlineMenuLabel": { + "message": "Zobrazit návrhy automatického vyplňování v polích formuláře" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Zobrazit návrhy, když je vybrána ikona" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Použije se na všechny přihlášené účty." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Když je vybrána ikona automatického vyplňování", "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" + }, "enableAutoFillOnPageLoad": { "message": "Automaticky vyplnit údaje při načtení stránky" }, "enableAutoFillOnPageLoadDesc": { "message": "Pokud je zjištěn přihlašovací formulář, automaticky se při načítání webové stránky vyplní přihlašovací údaje." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Varování:$CLOSETAG$ Kompromitované nebo nedůvěryhodné webové stránky mohou využívat automatické vyplňování při načítání stránky.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Kompromitované nebo nedůvěryhodné webové stránky mohou zneužívat automatické vyplňování při načítání stránky." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Další informace o rizicích" + }, "learnMoreAboutAutofill": { "message": "Více informací o automatickém vyplňování" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Zaškrtávací políčko" + }, "cfTypeLinked": { "message": "Propojené", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Vaše nové hlavní heslo nesplňuje požadavky zásad organizace." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Dostávejte do své e-mailové schránky rady, oznámení a příležitosti k výzkumu od společnosti Bitwarden." }, "unsubscribe": { "message": "Odhlásit odběr" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Zásady organizace zablokovaly importování položek do Vašeho osobního trezoru." }, + "domainsTitle": { + "message": "Domény", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Vyloučené domény" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden nebude žádat o uložení přihlašovacích údajů pro tyto domény pro všechny přihlášené účty. Aby se změny projevily, musíte stránku obnovit." }, + "websiteItemLabel": { + "message": "Webová stránka $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ není platná doména", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Vyloučené změny domény byly uloženy" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Chráněno heslem" }, + "copyLink": { + "message": "Kopírovat odkaz" + }, "copySendLink": { "message": "Zkopírovat odkaz Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Nastavení automatického vyplňování" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Zkrátka automatického vyplňování" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Změnit zkratku" + }, "autofillShortcut": { - "message": "Klávesová kombinace pro automatické vyplňování" + "message": "Klávesová zkratka pro automatické vyplňování" }, "autofillShortcutNotSet": { - "message": "Klávesová kombinace pro automatické vyplňování není nastavena. Změňte ji v nastavení prohlížeče." + "message": "Klávesová zkratka pro automatické vyplňování není nastavena. Změňte ji v nastavení prohlížeče." }, "autofillShortcutText": { - "message": "Klávesová kombinace pro automatické vyplňování je: $COMMAND$. Změňte ji v nastavení prohlížeče.", + "message": "Klávesová zkratka pro automatické vyplňování: $COMMAND$. Změňte ji v nastavení prohlížeče.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Odemkněte Váš účet pro zobrazení odpovídajících přihlašovacích údajů", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Odemkněte Váš účet pro zobrazení návrhů automatického vyplňování", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Odemknout účet", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Odemknout účet, otevře se v novém okně", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Vyplnit přihlašovací údaje pro", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Přidat novou položku trezoru", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Nové přihlášení", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Přidat do trezoru novou položku pro přihlášení, otevře se v novém okně", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Nová karta", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Přidat do trezoru novou položku karty, otevře se v novém okně", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "Nová identita", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Přidat do trezoru novou identitu, otevře se v novém okně", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Nabídka automatického vyplňování Bitwardenu. Pro výběr stiskněte šipku dolů.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Neplatné heslo souboru, použijte heslo zadané při vytvoření souboru exportu." }, - "importDestination": { - "message": "Cíl importu" + "destination": { + "message": "Cíl" }, "learnAboutImportOptions": { "message": "Více o volbách importu" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Společné formáty", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Pokračovat do nastavení prohlížeče?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Pokračovat do Centra nápovědy?", + "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.", + "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": "Můžete zobrazit a nastavit zkratky rozšíření v nastavení prohlížeče.", + "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.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Můžete zobrazit a nastavit zkratky rozšíření v nastavení prohlížeče.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Nastavit Bitwarden jako výchozí správce hesel?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Žádné hodnoty ke zkopírování" }, - "assignCollections": { - "message": "Přiřadit kolekce" + "assignToCollections": { + "message": "Přiřadit ke kolekcím" }, "copyEmail": { "message": "Kopírovat e-mail" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "číslo karty končí", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Přihlašovací údaje" }, @@ -3650,10 +3788,10 @@ "message": "Ověřovací klíč" }, "cardDetails": { - "message": "Card details" + "message": "Podrobnosti karty" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "Podrobnosti o $BRAND$", "placeholders": { "brand": { "content": "$1", @@ -3667,10 +3805,16 @@ "loading": { "message": "Načítání" }, + "data": { + "message": "Data" + }, "assign": { "message": "Přiřadit" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Jen členové organizace s přístupem k těmto kolekcím budou moci vidět položku." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Jen členové organizace s přístupem k těmto kolekcím budou moci vidět položky." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Vyberte kolekce pro přiřazení" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ bude trvale převedeno do vybrané organizace. Tyto položky již nebudete vlastnit.", + "personalItemTransferWarningSingular": { + "message": "1 položka bude trvale převedena do vybrané organizace. Tuto položku již nebudete vlastnit." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ položek bude trvale převedeno do vybrané organizace. Tyto položky již nebudete vlastnit.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ bude trvale převedeno do $ORG$. Tyto položky již nebudete vlastnit.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 položka bude trvale převedena do $ORG$. Tuto položku již nebudete vlastnit.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ položek bude trvale převedeno do $ORG$. Tyto položky již nebudete vlastnit.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Položky přesunuty do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Položka přesunuta do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ - přesunuto dolů, pozice $INDEX$ z $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Umístění položky" } } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 39ddf6ff5cc..207313e287c 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -13,11 +13,14 @@ "loginOrCreateNewAccount": { "message": "Mewngofnodwch neu crëwch gyfrif newydd i gael mynediad i'ch cell ddiogel." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Creu cyfrif" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Gosod cyfrinair cryf" }, "finishCreatingYourAccountBySettingAPassword": { "message": "Finish creating your account by setting a password" @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -454,7 +463,7 @@ "message": "Gosodiadau eraill" }, "unlockMethods": { - "message": "Unlock options" + "message": "Dewisiadau datgloi" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "Set up an unlock method to change your vault timeout action." @@ -466,7 +475,7 @@ "message": "Session timeout" }, "otherOptions": { - "message": "Other options" + "message": "Dewisiadau eraill" }, "rateExtension": { "message": "Rhoi eich barn ar yr estyniad" @@ -557,10 +566,10 @@ "message": "Diogelwch" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "Cadarnhau'r prif gyfrinair" }, "masterPassword": { - "message": "Master password" + "message": "Prif gyfrinair" }, "masterPassImportant": { "message": "Your master password cannot be recovered if you forget it!" @@ -736,6 +745,10 @@ "newUri": { "message": "URI newydd" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Eitem wedi'i hychwanegu" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -836,7 +858,7 @@ "message": "Datgloi" }, "additionalOptions": { - "message": "Additional options" + "message": "Dewisiadau ychwanegol" }, "enableContextMenuItem": { "message": "Show context menu options" @@ -1220,7 +1242,16 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,14 +1272,33 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { "message": "Llenwi'n awtomatig wrth i dudalen lwytho os canfyddir ffurflen mewngofnodi." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { "message": "Dysgu mwy am lenwi'n awtomatig" @@ -1257,7 +1307,7 @@ "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Defnyddio'r gosodiad rhagosodedig" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Gwerth Boole" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Parthau wedi'u heithrio" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "Dyw $DOMAIN$ ddim yn barth dilys", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Gosodiadau llenwi awtomatig" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2744,13 +2822,13 @@ "message": "and continue creating your account." }, "noEmail": { - "message": "No email?" + "message": "Dim ebost?" }, "goBack": { - "message": "Go back" + "message": "Ewch yn ôl" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "i olygu eich cyfeiriad ebost." }, "eu": { "message": "UE", @@ -2967,13 +3045,21 @@ "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "Datglowch eich cyfrif i weld manylion mewngofnodi sy'n cyfateb", + "description": "Text to display in overlay when the account is locked." + }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "Datgloi eich cyfrif", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Ychwanegu eitem newydd i'r gell", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3039,7 +3149,7 @@ "message": "Verification required for this action. Set a PIN to continue." }, "setPin": { - "message": "Set PIN" + "message": "Gosod PIN" }, "verifyWithBiometrics": { "message": "Verify with biometrics" @@ -3057,10 +3167,10 @@ "message": "Use master password" }, "usePin": { - "message": "Use PIN" + "message": "Defnyddio PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Defnyddio biometreg" }, "enterVerificationCodeSentToEmail": { "message": "Enter the verification code that was sent to your email." @@ -3110,11 +3220,11 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "Dysgu am eich dewisiadau mewnforio" }, "selectImportFolder": { "message": "Select a folder" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Fformatau cyffredin", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Hoffech chi wneud Bitwarden yn rheolydd cyfrineiriau rhagosodedig?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3496,7 +3630,7 @@ "message": "Notifications" }, "appearance": { - "message": "Appearance" + "message": "Golwg" }, "errorAssigningTargetCollection": { "message": "Error assigning target collection." @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3662,15 +3800,21 @@ } }, "addAccount": { - "message": "Add account" + "message": "Ychwanegu cyfrif" }, "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3689,7 +3833,7 @@ "message": "Add field" }, "add": { - "message": "Add" + "message": "Ychwanegu" }, "fieldType": { "message": "Field type" @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 6433d570d5a..d3ae27f227c 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log ind eller opret en ny konto for at få adgang til din sikre boks." }, + "inviteAccepted": { + "message": "Invitation accepteret" + }, "createAccount": { "message": "Opret konto" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Hovedadgangskodetip (valgfrit)" }, + "joinOrganization": { + "message": "Bliv medlem af organisation" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Færdiggør tilmeldingen til denne organisation ved at opsætte en hovedadgangskode." + }, "tab": { "message": "Fane" }, @@ -661,19 +670,19 @@ "message": "Din login-session er udløbet." }, "logIn": { - "message": "Log in" + "message": "Log ind" }, "restartRegistration": { - "message": "Restart registration" + "message": "Genstart registrering" }, "expiredLink": { - "message": "Expired link" + "message": "Udløbet link" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Genstart registreringen eller prøv at logge ind." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Har allerede oprettet en konto?" }, "logOutConfirmation": { "message": "Er du sikker på, du vil logge ud?" @@ -736,6 +745,10 @@ "newUri": { "message": "Ny URI" }, + "addDomain": { + "message": "Tilføj domæne", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Element tilføjet" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Spørg om at tilføje login" }, + "vaultSaveOptionsTitle": { + "message": "Gem i boksindstillinger" + }, "addLoginNotificationDesc": { "message": "Spørg om at tilføje et element, hvis et ikke findes i din boks." }, "addLoginNotificationDescAlt": { "message": "Anmod om at tilføje et emne, hvis intet ikke findes i boksen. Gælder alle indloggede konti." }, + "showCardsInVaultView": { + "message": "Vis kort som Autoudfyldningsforslag ved Boks-visning" + }, "showCardsCurrentTab": { "message": "Vis kort på fanebladet" }, "showCardsCurrentTabDesc": { "message": "Vis kortelementer på fanebladet for nem auto-udfyldning." }, + "showIdentitiesInVaultView": { + "message": "Vis identiteter som Autoudfyldningsforslag ved Boks-visning" + }, "showIdentitiesCurrentTab": { "message": "Vis identiteter på fanebladet" }, @@ -1220,7 +1242,16 @@ "message": "Vis autoudfyld-menu i formularfelter", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autoudfyldningsforslag" + }, + "showInlineMenuLabel": { + "message": "Vis autoudfyld-menu i formularfelter" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Vis forslag, når ikonet vælges" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Gælder for alle indloggede konti." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,14 +1272,33 @@ "message": "Når autoudfyld-ikon vælges", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autoudfyld ved sideindlæsning" + }, "enableAutoFillOnPageLoad": { "message": "Auto-udfyld ved sideindlæsning" }, "enableAutoFillOnPageLoadDesc": { "message": "Hvis der registreres en loginformular, så auto-udfyld, når websiden indlæses." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Advarsel:$CLOSETAG$ Kompromitterede eller ikke-betroede websteder kan misbruge autofyld ved sideindlæsning.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Kompromitterede eller ikke-betroede websteder kan udnytte autoudfyldning ved sideindlæsning." + "message": "Kompromitterede eller ikke-betroede websteder kan misbruge autoudfyldning ved sideindlæsning." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Læs mere om risici" }, "learnMoreAboutAutofill": { "message": "Læs mere om autoudfyldning" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolsk" }, + "cfTypeCheckbox": { + "message": "Afkrydsningsfelt" + }, "cfTypeLinked": { "message": "Forbundet", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Din nye hovedadgangskode opfylder ikke politikkravene." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Få råd, bekendtgørelser og forskningsmuligheder fra Bitwarden i indbakken." }, "unsubscribe": { "message": "Afmeld" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "En organisationspolitik hindrer import af emner til den individuelle boks." }, + "domainsTitle": { + "message": "Domæner", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Ekskluderede domæner" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden vil ikke anmode om at gemme login-detaljer for disse domæner for alle indloggede konti. Siden skal opfriskes for at effektuere ændringerne." }, + "websiteItemLabel": { + "message": "Websted $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ er ikke et gyldigt domæne", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Ekskluderet domæne-ændringer gemt" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Kodeordsbeskyttet" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopiér Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Autoudfyldelsesindstillinger" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autoudfyld-genvej" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Ændre genvej" + }, "autofillShortcut": { "message": "Autoudfyld-tastaturgenvej" }, @@ -2970,10 +3048,18 @@ "message": "Oplås kontoen for at se matchende logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Oplås kontoen for at få vist autoudfyldningsforslag", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Oplås konto", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Oplås kontoen, åbnes i et nyt vindue", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Angiv legitimationsoplysninger for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Tilføj nyt Boks-emne", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Nyt login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Tilføj nyt boks-login emne, åbnes i et nyt vindue", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Nyt kort", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Tilføj nyt boks-kort emne, åbnes i et nyt vindue", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "Ny identitet", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Tilføj nyt boks-identitetsemne, åbnes i et nyt vindue", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden autoudfyld-menu tilgængelig. Tryk på pil ned-tasten for at vælge.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Ugyldig filadgangskode. Brug samme adgangskode som under oprettelsen af eksportfilen." }, - "importDestination": { - "message": "Importdestination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Læs om importmuligheder" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Almindelige formater", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Fortsæt til Browserindstillinger?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Fortsæt til Hjælpecenter?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Skift browserens indstillinger for autofyldning og adgangskodehåndtering.", + "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": "Man kan se og indstille udvidelsesgenveje via Browserindstillinger.", + "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": "Skift browserens indstillinger for autofyldning og adgangskodehåndtering.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Man kan se og indstille udvidelsesgenveje via Browserindstillinger.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Lad Bitwarden håndtere adgangskoder som standard?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Ingen værdier at kopiere" }, - "assignCollections": { - "message": "Tildel samlinger" + "assignToCollections": { + "message": "Tildel til samlinger" }, "copyEmail": { "message": "Kopiér e-mail" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "kortnummer slutter med", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login-legitimationsoplysninger" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Indlæser" }, + "data": { + "message": "Data" + }, "assign": { "message": "Tildel" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Kun organisationsmedlemmer med adgang til disse samlinger vil kunne se emnet." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Kun organisationsmedlemmer med adgang til disse samlinger vil kunne se emnerne." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Vælg samlinger at tildele" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ overføres permanent til den valgte organisation. Man vil ikke længere eje disse emner.", + "personalItemTransferWarningSingular": { + "message": "1 emne overføres permanent til den valgte organisation. Man vil ikke længere være ejeren af dette emne." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ emner overføres permanent til den valgte organisation. Man vil ikke længere være ejeren af disse emner.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ overføres permanent til $ORG$. Man vil ikke længere eje disse emner.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 emne overføres permanent til $ORG$. Man vil ikke længere være ejeren af dette emne.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ emner overføres permanent til $ORG$. Man vil ikke længere være ejeren af disse emner.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Emner flyttet til $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Emne flyttet til $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ flyttet ned, position $INDEX$ af $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Emneplacering" } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 689846fbf60..a2034eda73f 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Melde dich an oder erstelle ein neues Konto, um auf deinen Tresor zuzugreifen." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Konto erstellen" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master-Passwort-Hinweis (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Sicherheitscode kopieren" }, "autoFill": { - "message": "Auto-Ausfüllen" + "message": "Automatisch ausfüllen" }, "autoFillLogin": { "message": "Zugangsdaten automatisch ausfüllen" @@ -661,19 +670,19 @@ "message": "Ihre Login-Sitzung ist abgelaufen." }, "logIn": { - "message": "Log in" + "message": "Anmelden" }, "restartRegistration": { - "message": "Restart registration" + "message": "Registrierung neu starten" }, "expiredLink": { - "message": "Expired link" + "message": "Abgelaufener Link" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Bitte starte die Registrierung erneut oder versuche dich anzumelden." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Du hast möglicherweise bereits ein Konto" }, "logOutConfirmation": { "message": "Bist du sicher, dass du dich abmelden willst?" @@ -736,6 +745,10 @@ "newUri": { "message": "Neue URL" }, + "addDomain": { + "message": "Domain hinzufügen", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Eintrag hinzugefügt" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Nach dem Hinzufügen von Zugangsdaten fragen" }, + "vaultSaveOptionsTitle": { + "message": "Optionen zum Speichern im Tresor" + }, "addLoginNotificationDesc": { "message": "Nach dem Hinzufügen eines Eintrags fragen, wenn dieser nicht in deinem Tresor gefunden wurde." }, "addLoginNotificationDescAlt": { "message": "Nach dem Hinzufügen eines Eintrags fragen, wenn er nicht in deinem Tresor gefunden wurde. Gilt für alle angemeldeten Konten." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Karten auf Tab Seite anzeigen" }, "showCardsCurrentTabDesc": { "message": "Karten-Einträge auf der Tab Seite anzeigen, um das Auto-Ausfüllen zu vereinfachen." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Identitäten auf Tab Seite anzeigen" }, @@ -1220,8 +1242,17 @@ "message": "Auto-Ausfüllen Menü in Formularfeldern anzeigen", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Gilt für alle angemeldeten Konten." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Deaktiviere die Einstellungen des eingebauten Passwort-Managers deines Browsers, um Konflikte zu vermeiden." @@ -1241,15 +1272,34 @@ "message": "Wenn das Auto-Ausfüllen Symbol ausgewählt ist", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Auto-Ausfüllen beim Laden einer Seite aktivieren" }, "enableAutoFillOnPageLoadDesc": { "message": "Wenn eine Anmeldemaske erkannt wird, die Zugangsdaten automatisch ausfüllen während die Webseite lädt." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Kompromittierte oder nicht vertrauenswürdige Websites können Auto-Ausfüllen beim Laden der Seite ausnutzen." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Erfahre mehr über Auto-Ausfüllen" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Ja/Nein" }, + "cfTypeCheckbox": { + "message": "Kontrollkästchen" + }, "cfTypeLinked": { "message": "Verknüpft", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Ihr neues Master-Passwort entspricht nicht den Anforderungen der Richtlinie." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Erhalte Ratschläge, Ankündigungen und Marktforschungsumfragen von Bitwarden in deinem Posteingang." }, "unsubscribe": { "message": "Deabonnieren" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Eine Organisationsrichtlinie hat das Importieren von Einträgen in deinen persönlichen Tresor deaktiviert." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Ausgeschlossene Domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden wird für alle angemeldeten Konten nicht danach fragen Zugangsdaten für diese Domains speichern. Du musst die Seite neu laden, damit die Änderungen wirksam werden." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ ist keine gültige Domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Änderungen der ausgeschlossenen Domain gespeichert" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Passwortgeschützt" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send-Link kopieren", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Auto-Ausfüllen Einstellungen" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Auto-Ausfüllen Tastaturkürzel" }, @@ -2970,10 +3048,18 @@ "message": "Entsperre dein Konto, um passende Zugangsdaten anzuzeigen", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Konto entsperren", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Zugangsdaten ausfüllen für", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Neuen Tresor-Eintrag hinzufügen", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden Auto-Ausfüllen Menü verfügbar. Drücke die Pfeiltaste nach unten zum Auswählen.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Ungültiges Dateipasswort. Bitte verwende das Passwort, das du beim Erstellen der Exportdatei eingegeben hast." }, - "importDestination": { - "message": "Import-Ziel" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Erfahre mehr über deine Importoptionen" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Gängigste Formate", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Bitwarden zum Standard-Passwort-Manager machen?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Keine Werte zum Kopieren" }, - "assignCollections": { - "message": "Sammlungen zuweisen" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "E-Mail-Adresse kopieren" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Zugangsdaten" }, @@ -3667,11 +3805,17 @@ "loading": { "message": "Wird geladen" }, + "data": { + "message": "Data" + }, "assign": { "message": "Zuweisen" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Nur Organisationsmitglieder mit Zugriff auf diese Sammlungen können die Einträge sehen." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { "message": "Du hast $TOTAL_COUNT$ Einträge ausgewählt. Du kannst $READONLY_COUNT$ der Einträge nicht aktualisieren, da du keine Bearbeitungsrechte hast.", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Zu zuweisende Sammlungen auswählen" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an die ausgewählte Organisation übertragen. Du wirst diese Einträge nicht mehr besitzen.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an $ORG$ übertragen. Du wirst diese Einträge nicht mehr besitzen.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ nach unten verschoben, Position $INDEX$ von $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Eintrags-Standort" } } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 10422951202..22470a1f1e9 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Συνδεθείτε ή δημιουργήστε ένα νέο λογαριασμό για να αποκτήσετε πρόσβαση στο ασφαλές vault σας." }, + "inviteAccepted": { + "message": "Η πρόσκληση έγινε αποδεκτή" + }, "createAccount": { "message": "Δημιουργία λογαριασμού" }, @@ -38,7 +41,7 @@ "message": "Υποβολή" }, "emailAddress": { - "message": "Διεύθυνση ηλεκτρονικού ταχυδρομείου" + "message": "Διεύθυνση ηλ. ταχυδρομείου" }, "masterPass": { "message": "Κύριος κωδικός πρόσβασης" @@ -50,7 +53,7 @@ "message": "Η υπόδειξη του κύριου κωδικού μπορεί να σας βοηθήσει να θυμηθείτε τον κωδικό σας, σε περίπτωση που τον ξεχάσετε." }, "masterPassHintText": { - "message": "Αν ξεχάσετε τον κωδικό πρόσβασής σας, η υπενθύμιση του μπορεί να σταλεί στο ηλεκτρονικό ταχυδρομείο σας. $CURRENT$/$MAXIMUM$ μέγιστοι χαρακτήρες.", + "message": "Αν ξεχάσετε τον κωδικό πρόσβασής σας, η υπενθύμιση του μπορεί να σταλεί στο ηλ. ταχυδρομείο σας. $CURRENT$/$MAXIMUM$ μέγιστοι χαρακτήρες.", "placeholders": { "current": { "content": "$1", @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Υπόδειξη κύριου κωδικού πρόσβασης (προαιρετικό)" }, + "joinOrganization": { + "message": "Συμμετοχή στον οργανισμό" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Ολοκληρώστε τη συμμετοχή σας σε αυτόν τον οργανισμό ορίζοντας έναν κύριο κωδικό πρόσβασης." + }, "tab": { "message": "Καρτέλα" }, @@ -643,10 +652,10 @@ "message": "Κάντε την επαλήθευση δύο βημάτων απρόσκοπτη" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Το Bitwarden μπορεί να αποθηκεύσει και να συμπληρώσει τους κωδικούς επαλήθευσης 2 βημάτων. Αντιγράψτε και επικολλήστε το κλειδί σε αυτό το πεδίο." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Το Bitwarden μπορεί να αποθηκεύσει και να συμπληρώσει τους κωδικούς επαλήθευσης 2 βημάτων. Επιλέξτε το εικονίδιο της κάμερας για λήψη στιγμιότυπου του κωδικού QR του αυθεντικοποιητή αυτής της ιστοσελίδας, ή αντιγράψτε και επικολλήστε το κλειδί σε αυτό το πεδίο." }, "copyTOTP": { "message": "Αντιγραφή κλειδιού Αυθεντικοποιητή (TOTP)" @@ -661,19 +670,19 @@ "message": "Η περίοδος σύνδεσης σας έχει λήξει." }, "logIn": { - "message": "Log in" + "message": "Σύνδεση" }, "restartRegistration": { - "message": "Restart registration" + "message": "Επανεκκίνηση εγγραφής" }, "expiredLink": { - "message": "Expired link" + "message": "Ο σύνδεσμος έληξε" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Παρακαλούμε επανακκινήστε την εγγραφή ή δοκιμάστε να συνδεθείτε." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Μπορεί να έχετε ήδη λογαριασμό" }, "logOutConfirmation": { "message": "Είστε βέβαιοι ότι θέλετε να αποσυνδεθείτε;" @@ -694,7 +703,7 @@ "message": "Προστέθηκε φάκελος" }, "twoStepLoginConfirmation": { - "message": "Η σύνδεση δύο βημάτων καθιστά πιο ασφαλή τον λογαριασμό σας, απαιτώντας να επαληθεύσετε τη συνδεσή σας με μια άλλη συσκευή, όπως ένα κλειδί ασφαλείας, μία εφαρμογή επαλήθευσης, ένα μήνυμα SMS, μία τηλεφωνική κλήση ή ένα μήνυμα ηλεκτρονικου ταχυδρομείου. Μπορείτε να ενεργοποιήσετε τη σύνδεση δύο βημάτων στο διαδικτυακό θυσαυ/κιο bitwarden.com. Θέλετε να επισκεφθείτε την ιστοσελίδα τώρα;" + "message": "Η σύνδεση δύο βημάτων καθιστά πιο ασφαλή τον λογαριασμό σας, απαιτώντας να επαληθεύσετε τη συνδεσή σας με μια άλλη συσκευή, όπως ένα κλειδί ασφαλείας, μία εφαρμογή επαλήθευσης, ένα μήνυμα SMS, μία τηλεφωνική κλήση ή ένα μήνυμα ηλ. ταχυδρομείου. Μπορείτε να ενεργοποιήσετε τη σύνδεση δύο βημάτων στο διαδικτυακό θυσαυ/κιο bitwarden.com. Θέλετε να επισκεφθείτε την ιστοσελίδα τώρα;" }, "editedFolder": { "message": "Ο φάκελος αποθηκεύτηκε" @@ -736,6 +745,10 @@ "newUri": { "message": "Νέο URI" }, + "addDomain": { + "message": "Προσθήκη τομέα", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Το στοιχείο προστέθηκε" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ζητήστε να προσθέσετε σύνδεση" }, + "vaultSaveOptionsTitle": { + "message": "Αποθήκευση στις επιλογές θησαυ/κίου" + }, "addLoginNotificationDesc": { "message": "Η \"Προσθήκη Ειδοποίησης Σύνδεσης\" σας προτρέπει αυτόματα να αποθηκεύσετε νέες συνδέσεις στο vault σας κάθε φορά που θα συνδεθείτε για πρώτη φορά." }, "addLoginNotificationDescAlt": { "message": "Ζητήστε να προσθέσετε ένα αντικείμενο αν δε βρεθεί στο θησαυ/κιό σας. Ισχύει για όλους τους συνδεδεμένους λογαριασμούς." }, + "showCardsInVaultView": { + "message": "Εμφάνιση καρτών ως προτάσεις αυτόματης συμπλήρωσης στην προβολή Θησαυ/κίου" + }, "showCardsCurrentTab": { "message": "Εμφάνιση καρτών στη σελίδα Καρτέλας" }, "showCardsCurrentTabDesc": { "message": "Λίστα αντικειμένων καρτών στη σελίδα Καρτέλας για εύκολη αυτόματη συμπλήρωση." }, + "showIdentitiesInVaultView": { + "message": "Εμφάνιση ταυτοτήτων ως προτάσεις αυτόματης συμπλήρωσης στην προβολή Θησαυ/κίου" + }, "showIdentitiesCurrentTab": { "message": "Εμφάνιση ταυτοτήτων στη σελίδα καρτέλας" }, @@ -821,7 +843,7 @@ "message": "Ρώτησε για αποθήκευση και χρήση κλειδιών πρόσβασης" }, "usePasskeysDesc": { - "message": "Ask to save new passkeys or log in with passkeys stored in your vault. Applies to all logged in accounts." + "message": "Ρώτησε με για την αποθήκευση νέων συνθηματικών ή σύνδεση με κλειδιά πρόσβασης αποθηκευμένα στο θησαυ/κιό μου. Ισχύει για όλους τους συνδεδεμένους λογαριασμούς." }, "notificationChangeDesc": { "message": "Θέλετε να ενημερώσετε αυτό τον κωδικό στο Bitwarden ;" @@ -845,7 +867,7 @@ "message": "Χρησιμοποιήστε ένα δευτερεύον κλικ για να αποκτήσετε πρόσβαση στη δημιουργία κωδικού πρόσβασης και να ταιριάξετε τις συνδέσεις για την ιστοσελίδα. " }, "contextMenuItemDescAlt": { - "message": "Use a secondary click to access password generation and matching logins for the website. Applies to all logged in accounts." + "message": "Χρησιμοποιήστε ένα δευτερεύον κλικ για να αποκτήσετε πρόσβαση στη δημιουργία κωδικού πρόσβασης και να ταιριάξετε συνδέσεις για την ιστοσελίδα. Ισχύει για όλους τους συνδεδεμένους λογαριασμούς." }, "defaultUriMatchDetection": { "message": "Προεπιλεγμένη ανίχνευση αντιστοιχίας URI", @@ -861,7 +883,7 @@ "message": "Αλλαγή χρώματος θέματος εφαρμογής." }, "themeDescAlt": { - "message": "Change the application's color theme. Applies to all logged in accounts." + "message": "Αλλαγή του χρωματικού θέματος της εφαρμογής. Ισχύει για όλους τους συνδεδεμένους λογαριασμούς." }, "dark": { "message": "Σκοτεινό", @@ -931,7 +953,7 @@ "message": "Κοινοποιήθηκε" }, "bitwardenForBusinessPageDesc": { - "message": "Bitwarden for Business allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website." + "message": "Το Bitwarden για Επιχειρήσεις σας επιτρέπει να μοιραστείτε τα αντικείμενα του θησαυ/κίου σας με άλλους χρησιμοποιώντας έναν οργανισμό. Μάθετε περισσότερα στην ιστοσελίδα bitwarden.com." }, "moveToOrganization": { "message": "Μετακίνηση σε οργανισμό" @@ -1145,7 +1167,7 @@ "message": "Εφαρμογή αυθεντικοποίησης" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Εισάγετε έναν κωδικό που δημιουργήθηκε από μια εφαρμογή αυθεντικοποίησης όπως το Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { @@ -1172,7 +1194,7 @@ "message": "Email" }, "emailDescV2": { - "message": "Εισάγετε έναν κωδικό που σας στάλθηκε στο ηλεκτρονικό ταχυδρομείο σας." + "message": "Εισάγετε τον κωδικό που σας στάλθηκε στο ηλ. ταχυδρομείο." }, "selfHostedEnvironment": { "message": "Αυτο-εξυπηρετούμενο περιβάλλον" @@ -1181,7 +1203,7 @@ "message": "Καθορίστε τη βασική διεύθυνση URL, της εγκατάστασης του Bitwarden που φιλοξενείται στο χώρο σας." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Καθορίστε το βασικό URL της εγκατάστασης Bitwarden στο χώρο σας. Παράδειγμα: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { "message": "Για προχωρημένη παραμετροποίηση, μπορείτε να ορίσετε ανεξάρτητα το βασικό URL κάθε υπηρεσίας." @@ -1220,11 +1242,20 @@ "message": "Εμφάνιση μενού αυτόματης συμπλήρωσης στα πεδία της φόρμας", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Πρόταση αυτόματης συμπλήρωσης" + }, + "showInlineMenuLabel": { + "message": "Εμφάνιση μενού αυτόματης συμπλήρωσης στα πεδία της φόρμας" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Εμφάνιση προτάσεων όταν το εικονίδιο είναι επιλεγμένο" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Ισχύει για όλους τους συνδεδεμένους λογαριασμούς." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Απενεργοποιήστε την ρύθμιση του διαχειριστή κωδικών πρόσβασης του περιηγητή σας για να αποφύγετε συγκρούσεις." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Επεξεργαστείτε τις ρυθμίσεις του περιηγητή." @@ -1234,22 +1265,41 @@ "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "Όταν το πεδίο είναι επιλεγμένο (σε εστίαση)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { "message": "Όταν το εικονίδιο αυτόματης συμπλήρωσης είναι επιλεγμένο", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Αυτόματη συμπλήρωση κατά την φόρτωση της σελίδας" + }, "enableAutoFillOnPageLoad": { "message": "Ενεργοποίηση αυτόματης συμπλήρωσης κατά την φόρτωση της σελίδας" }, "enableAutoFillOnPageLoadDesc": { "message": "Εάν εντοπιστεί μια φόρμα σύνδεσης, πραγματοποιείται αυτόματα μια αυτόματη συμπλήρωση όταν φορτώνεται η ιστοσελίδα." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Προειδοποίηση:$CLOSETAG$ Οι παραβιασμένες ή μη αξιόπιστες ιστοσελίδες μπορούν να εκμεταλλευτούν την αυτόματη συμπλήρωση κατά τη φόρτωση της σελίδας.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Παραβιασμένοι ή μη αξιόπιστοι ιστότοποι μπορούν να εκμεταλλευτούν την αυτόματη συμπλήρωση κατά τη φόρτωση της σελίδας." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Μάθετε περισσότερα σχετικά με τους κινδύνους" + }, "learnMoreAboutAutofill": { "message": "Μάθετε περισσότερα σχετικά με την αυτόματη συμπλήρωση" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Δυαδικό" }, + "cfTypeCheckbox": { + "message": "Πλαίσιο επιλογής" + }, "cfTypeLinked": { "message": "Συνδεδεμένο", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1746,13 +1799,13 @@ "message": "Είστε βέβαιοι ότι θέλετε να διαγράψετε μόνιμα αυτό το στοιχείο;" }, "permanentlyDeletedItem": { - "message": "Μόνιμα Διεγραμμένο Στοιχείο" + "message": "Το αντικείμενο διαγράφηκε οριστικά" }, "restoreItem": { - "message": "Ανάκτηση Στοιχείου" + "message": "Επαναφορά αντικειμένου" }, "restoredItem": { - "message": "Στοιχείο που έχει Ανακτηθεί" + "message": "Το αντικείμενο επαναφέρθηκε" }, "alreadyHaveAccount": { "message": "Έχετε ήδη λογαριασμό;" @@ -1761,7 +1814,7 @@ "message": "Η αποσύνδεση θα καταργήσει όλη την πρόσβαση στο vault σας και απαιτεί online έλεγχο ταυτότητας μετά το χρονικό όριο λήξης. Είστε βέβαιοι ότι θέλετε να χρησιμοποιήσετε αυτήν τη ρύθμιση;" }, "vaultTimeoutLogOutConfirmationTitle": { - "message": "Επιβεβαίωση Ενέργειας Χρονικού Ορίου" + "message": "Επιβεβαίωση ενέργειας χρονικού ορίου λήξης" }, "autoFillAndSave": { "message": "Αυτόματη συμπλήρωση και αποθήκευση" @@ -1794,16 +1847,16 @@ } }, "setMasterPassword": { - "message": "Καθορισμός κύριου κωδικού" + "message": "Ορισμός κύριου κωδικού πρόσβασης" }, "currentMasterPass": { - "message": "Τρέχων Κύριος Κωδικός" + "message": "Τρέχων κύριος κωδικός πρόσβασης" }, "newMasterPass": { - "message": "Νέος κύριος κωδικός" + "message": "Νέος κύριος κωδικός πρόσβασης" }, "confirmNewMasterPass": { - "message": "Επιβεβαίωση Νέου Κύριου Κωδικού" + "message": "Επιβεβαίωση νέου κύριου κωδικού πρόσβασης" }, "masterPasswordPolicyInEffect": { "message": "Σε μία ή περισσότερες πολιτικές του οργανισμού απαιτείται ο κύριος κωδικός να πληρεί τις ακόλουθες απαιτήσεις:" @@ -1848,7 +1901,7 @@ "message": "Ο νέος κύριος κωδικός δεν πληροί τις απαιτήσεις πολιτικής." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Λάβετε συμβουλές, ανακοινώσεις και ευκαιρίες έρευνας από το Bitwarden στα εισερχόμενά σας." }, "unsubscribe": { "message": "Ακύρωση συνδρομής" @@ -1923,7 +1976,7 @@ "message": "Απόρριψη λογαριασμού" }, "biometricsNotEnabledTitle": { - "message": "Η βιομετρική δεν είναι ενεργοποιημένη" + "message": "Δεν έχουν οριστεί βιομετρικά" }, "biometricsNotEnabledDesc": { "message": "Τα βιομετρικά στοιχεία του προγράμματος περιήγησης απαιτούν την ενεργοποίηση της βιομετρικής επιφάνειας εργασίας στις ρυθμίσεις πρώτα." @@ -1941,7 +1994,7 @@ "message": "Παρακαλώ ξεκλειδώστε αυτόν τον χρήστη στην εφαρμογή επιφάνειας εργασίας και προσπαθήστε ξανά." }, "biometricsFailedTitle": { - "message": "Ο βιομετρικός έλεγχος απέτυχε" + "message": "Τα βιομετρικά απέτυχαν" }, "biometricsFailedDesc": { "message": "Τα βιομετρικά δεν μπόρεσαν να ολοκληρωθούν, σκεφτείτε να χρησιμοποιήσετε έναν κύριο κωδικό πρόσβασης ή να αποσυνδεθείτε. Αν αυτό εξακολουθεί να συμβαίνει, παρακαλώ επικοινωνήστε με την υποστήριξη της Bitwarden." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Μια οργανωτική πολιτική έχει αποτρέψει την εισαγωγή στοιχείων στο προσωπικό θησαυ/κιο σας." }, + "domainsTitle": { + "message": "Τομείς", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Εξαιρούμενοι Τομείς" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Το Bitwarden δε θα ρωτήσει για να αποθηκεύσετε τα στοιχεία σύνδεσης για αυτούς τους τομείς, για όλους τους συνδεδεμένους λογαριασμούς. Πρέπει να ανανεώσετε τη σελίδα για να τεθούν σε ισχύ οι αλλαγές." }, + "websiteItemLabel": { + "message": "Ιστοσελίδα $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "Το $DOMAIN$ δεν είναι έγκυρος τομέας", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Οι αλλαγές αποκλεισμένων τομέων αποθηκεύτηκαν" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Προστατευμένο με κωδικό" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Αντιγραφή συνδέσμου Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2031,10 +2103,10 @@ "message": "Διαγραφή" }, "removedPassword": { - "message": "Καταργήθηκε ο Κωδικός Πρόσβασης" + "message": "Ο κωδικός πρόσβασης αφαιρέθηκε" }, "deletedSend": { - "message": "Το Send Διαγράφηκε", + "message": "Το Send διαγράφηκε", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLink": { @@ -2071,14 +2143,14 @@ "message": "Το αρχείο που θέλετε να στείλετε." }, "deletionDate": { - "message": "Ημερομηνία Διαγραφής" + "message": "Ημερομηνία διαγραφής" }, "deletionDateDesc": { "message": "Το Send θα διαγραφεί οριστικά την καθορισμένη ημερομηνία και ώρα.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { - "message": "Ημερομηνία Λήξης" + "message": "Ημερομηνία λήξης" }, "expirationDateDesc": { "message": "Εάν οριστεί, η πρόσβαση σε αυτό το Send θα λήξει την καθορισμένη ημερομηνία και ώρα.", @@ -2130,17 +2202,17 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "currentAccessCount": { - "message": "Τρέχων Αριθμός Πρόσβασης" + "message": "Τρέχων αριθμός πρόσβασης" }, "createSend": { - "message": "Δημιουργία Νέου Send", + "message": "Νέο Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "newPassword": { - "message": "Νέος Κωδικός Πρόσβασης" + "message": "Νέος κωδικός πρόσβασης" }, "sendDisabled": { - "message": "Το Send Απενεργοποιήθηκε", + "message": "Το Send αφαιρέθηκε", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { @@ -2148,11 +2220,11 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSend": { - "message": "Το Send Δημιουργήθηκε", + "message": "Το Send δημιουργήθηκε", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { - "message": "Το Send Επεξεργάστηκε", + "message": "Το Send αποθηκεύτηκε", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -2210,10 +2282,10 @@ "message": "Αυτή η ενέργεια προστατεύεται. Για να συνεχίσετε, πληκτρολογήστε ξανά τον κύριο κωδικό πρόσβασης για να επαληθεύσετε την ταυτότητά σας." }, "emailVerificationRequired": { - "message": "Απαιτείται Επαλήθευση Email" + "message": "Απαιτείται επαλήθευση διεύθυνσης ηλ. ταχυδρομείου" }, "emailVerifiedV2": { - "message": "Διεύθυνση ηλεκτρονικού ταχυδρομείου επιβεβαιώθηκε" + "message": "Η διεύθυνση ηλ. ταχυδρομείου επιβεβαιώθηκε" }, "emailVerificationRequiredDesc": { "message": "Πρέπει να επαληθεύσετε το email σας για να χρησιμοποιήσετε αυτή τη δυνατότητα. Μπορείτε να επαληθεύσετε το email σας στο web vault." @@ -2222,7 +2294,7 @@ "message": "Ενημερώθηκε ο κύριος κωδικός πρόσβασης" }, "updateMasterPassword": { - "message": "Ενημερώστε τον κύριο κωδικό πρόσβασης" + "message": "Ενημέρωση κύριου κωδικού πρόσβασης" }, "updateMasterPasswordWarning": { "message": "Ο Κύριος Κωδικός Πρόσβασής σας άλλαξε πρόσφατα από διαχειριστή στον οργανισμό σας. Για να αποκτήσετε πρόσβαση στο vault, πρέπει να τον ενημερώσετε τώρα. Η διαδικασία θα σας αποσυνδέσει από την τρέχουσα συνεδρία σας, απαιτώντας από εσάς να συνδεθείτε ξανά. Οι ενεργές συνεδρίες σε άλλες συσκευές ενδέχεται να συνεχίσουν να είναι ενεργές για μία ώρα." @@ -2231,7 +2303,7 @@ "message": "Ο Κύριος κωδικός πρόσβασης δεν πληροί τις απαιτήσεις πολιτικής αυτού του οργανισμού. Για να έχετε πρόσβαση στο vault, πρέπει να ενημερώσετε τον Κύριο σας κωδικό άμεσα. Η διαδικασία θα σας αποσυνδέσει από την τρέχουσα συνεδρία σας, απαιτώντας από εσάς να συνδεθείτε ξανά. Οι ενεργές συνεδρίες σε άλλες συσκευές ενδέχεται να συνεχίσουν να είναι ενεργές για μία ώρα." }, "resetPasswordPolicyAutoEnroll": { - "message": "Αυτόματη Εγγραφή" + "message": "Αυτόματη εγγραφή" }, "resetPasswordAutoEnrollInviteWarning": { "message": "Αυτός ο οργανισμός έχει μια επιχειρηματική πολιτική που θα σας εγγράψει αυτόματα στην επαναφορά κωδικού. Η εγγραφή θα επιτρέψει στους διαχειριστές του οργανισμού να αλλάξουν τον κύριο κωδικό πρόσβασης σας." @@ -2382,14 +2454,14 @@ "message": "Τύπος ονόματος χρήστη" }, "plusAddressedEmail": { - "message": "Συν Διεύθυνση Email", + "message": "Συν διεύθυνση ηλ. ταχυδρομείου", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { "message": "Χρησιμοποιήστε τις δυνατότητες δευτερεύουσας διεύθυνσης του παρόχου email σας." }, "catchallEmail": { - "message": "Ηλεκτρονικό ταχυδρομείο για κάθε σκοπό" + "message": "Διεύθυνση ηλ. ταχυδρομείου κάθε σκοπού" }, "catchallEmailDesc": { "message": "Χρησιμοποιήστε τα διαμορφωμένα εισερχόμενα catch-all του domain σας." @@ -2413,7 +2485,7 @@ "message": "Υπηρεσία" }, "forwardedEmail": { - "message": "Προωθημένο ψευδώνυμο διεύθυνσης ηλεκτρονικού ταχυδρομείου" + "message": "Προωθημένο ψευδώνυμο διεύθυνσης ηλ. ταχυδρομείου" }, "forwardedEmailDesc": { "message": "Δημιουργήστε ένα alias email με μια εξωτερική υπηρεσία προώθησης." @@ -2471,7 +2543,7 @@ } }, "forwarderNoAccountId": { - "message": "Αδύνατη η απόκτηση του $SERVICENAME$ κρυφού ID λογαριασμού ηλεκτρονικού ταχυδρομείου.", + "message": "Αδύνατη η απόκτηση του $SERVICENAME$ καμουφλαρισμένου ID διεύθυνσης ηλ. ταχυδρομείου.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2600,7 +2672,7 @@ "message": "Είστε νέος/α εδώ;" }, "rememberEmail": { - "message": "Απομνημόνευση διεύθυνσης ηλεκτρονικού ταχυδρομείου" + "message": "Απομνημόνευση διεύθυνσης ηλ. ταχυδρομείου" }, "loginWithDevice": { "message": "Σύνδεση με τη χρήση συσκευής" @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Ρυθμίσεις αυτόματης συμπλήρωσης" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Συντόμευση αυτόματης συμπλήρωσης" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Αλλαγή συντόμευσης" + }, "autofillShortcut": { "message": "Συντόμευση πληκτρολογίου αυτόματης συμπλήρωσης" }, @@ -2687,7 +2765,7 @@ "message": "Η συντόμευση αυτόματης συμπλήρωσης δεν έχει οριστεί. Αλλάξτε τη στις ρυθμίσεις του περιηγητή." }, "autofillShortcutText": { - "message": "Η συντόμευση αυτόματης συμπλήρωσης είναι: $COMMAND$. Αλλάξτε τη στις ρυθμίσεις του προγράμματος περιήγησης.", + "message": "Η συντόμευση αυτόματης συμπλήρωσης είναι: $COMMAND$. Αλλάξτε τη στις ρυθμίσεις του περιηγητή.", "placeholders": { "command": { "content": "$1", @@ -2705,7 +2783,7 @@ } }, "loggingInOn": { - "message": "Σύνδεση ως" + "message": "Σύνδεση στο" }, "opensInANewWindow": { "message": "Ανοίγει σε νέο παράθυρο" @@ -2726,7 +2804,7 @@ "message": "Αίτηση έγκρισης διαχειριστή" }, "approveWithMasterPassword": { - "message": "Έγκριση με τον κύριο κωδικό" + "message": "Έγκριση με κύριο κωδικό πρόσβασης" }, "ssoIdentifierRequired": { "message": "Απαιτείται αναγνωριστικό οργανισμού SSO." @@ -2735,22 +2813,22 @@ "message": "Δημιουργία λογαριασμού στο" }, "checkYourEmail": { - "message": "Ελέγξτε το ηλεκτρονικό σας ταχυδρομείο" + "message": "Ελέγξτε το ηλ. ταχυδρομείο σας" }, "followTheLinkInTheEmailSentTo": { - "message": "Ακολουθήστε το σύνδεσμο στο μήνυμα ηλεκτρονικού ταχυδρομείου που στάλθηκε στο" + "message": "Ακολουθήστε το σύνδεσμο στο μήνυμα ηλ. ταχυδρομείου που στάλθηκε στο" }, "andContinueCreatingYourAccount": { "message": "και συνεχίστε στη δημιουργία του λογαριασμού σας." }, "noEmail": { - "message": "Δεν υπάρχει μήνυμα ηλεκτρονικού ταχυδρομείου;" + "message": "Κανένα μήνυμα ηλ. ταχυδρομείου;" }, "goBack": { "message": "Επιστροφή" }, "toEditYourEmailAddress": { - "message": "για να επεξεργαστείτε τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας." + "message": "για να επεξεργαστείτε τη διεύθυνση ηλ. ταχυδρομείου σας." }, "eu": { "message": "ΕΕ", @@ -2784,7 +2862,7 @@ "message": "Η σύνδεση εγκρίθηκε" }, "userEmailMissing": { - "message": "Το email του χρήστη απουσιάζει" + "message": "Η διεύθυνση ηλ. ταχυδρομείου του χρήστη λείπει" }, "deviceTrusted": { "message": "Αξιόπιστη συσκευή" @@ -2852,14 +2930,14 @@ } }, "multipleInputEmails": { - "message": "1 ή περισσότερα email δεν είναι έγκυρα" + "message": "1 ή περισσότερες διευθύνσεις ηλ. ταχυδρομείου δεν είναι έγκυρες" }, "inputTrimValidator": { "message": "Η καταχώρηση δεν πρέπει να περιέχει μόνο κενά.", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "Η καταχώρηση δεν είναι διεύθυνση email." + "message": "Η καταχώρηση δεν είναι διεύθυνση ηλ. ταχυδρομείου." }, "fieldsNeedAttention": { "message": "$COUNT$ Το/α παραπάνω πεδίo/α χρειάζονται την προσοχή σας.", @@ -2930,22 +3008,22 @@ "description": "Notification message for when an import has failed." }, "importNetworkError": { - "message": "Network error encountered during import.", + "message": "Εμφανίστηκε σφάλμα δικτύου κατά την εισαγωγή.", "description": "Notification message for when an import has failed due to a network error." }, "aliasDomain": { "message": "Συνώνυμο domain" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Items with master password re-prompt cannot be auto-filled on page load. Auto-fill on page load turned off.", + "message": "Τα αντικείμενα με υπόδειξη κύριου κωδικού πρόσβασης δεν μπορούν να συμπληρωθούν αυτόματα κατά τη φόρτωση της σελίδας. Η αυτόματη συμπλήρωση έχει απενεργοποιηθεί κατά τη φόρτωση της σελίδας.", "description": "Toast message for describing that master password re-prompt cannot be auto-filled on page load." }, "autofillOnPageLoadSetToDefault": { - "message": "Auto-fill on page load set to use default setting.", + "message": "Η αυτόματη συμπλήρωση κατά τη φόρτωση της σελίδας ορίστηκε να χρησιμοποιεί τις προεπιλεγμένες ρυθμίσεις.", "description": "Toast message for informing the user that auto-fill on page load has been set to the default setting." }, "turnOffMasterPasswordPromptToEditField": { - "message": "Turn off master password re-prompt to edit this field", + "message": "Απενεργοποιήστε την υπόδειξη κύριου κωδικού πρόσβασης για να επεξεργαστείτε αυτό το πεδίο", "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { @@ -2959,57 +3037,89 @@ "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Toggle Bitwarden auto-fill menu", + "message": "Εναλλαγή ορατότητας μενού αυτόματης συμπλήρωσης Bitwarden", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden auto-fill menu", + "message": "Μενού αυτόματης συμπλήρωσης Bitwarden", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "Ξεκλειδώστε τον λογαριασμό σας για να δείτε συνδέσεις που ταιριάζουν", + "description": "Text to display in overlay when the account is locked." + }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "Ξεκλείδωμα λογαριασμού", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { - "message": "Fill credentials for", + "message": "Συμπλήρωση στοιχείων για", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { - "message": "Partial username", + "message": "Μερικό όνομα χρήστη", "description": "Screen reader text for when a login item is focused where a partial username is displayed. SR will announce this phrase before reading the text of the partial username" }, "noItemsToShow": { - "message": "No items to show", + "message": "Δεν υπάρχουν αντικείμενα για προβολή", "description": "Text to show in overlay if there are no matching items" }, "newItem": { - "message": "New item", + "message": "Νέο αντικείμενο", "description": "Button text to display in overlay when there are no matching items" }, "addNewVaultItem": { - "message": "Add new vault item", + "message": "Προσθήκη νέου αντικειμένου θησαυ/κίου", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { - "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", + "message": "Είναι διαθέσιμο το Bitwarden μενού αυτόματης συμπλήρωσης. Πατήστε το πλήκτρο κάτω βέλος για να επιλέξετε.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { - "message": "Turn on" + "message": "Ενεργοποίηση" }, "ignore": { - "message": "Ignore" + "message": "Παράβλεψη" }, "importData": { "message": "Εισαγωγή δεδομένων", "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" }, "importError": { - "message": "Σφάλμα κατά την εισαγωγή" + "message": "Σφάλμα εισαγωγής" }, "importErrorDesc": { "message": "Παρουσιάστηκε πρόβλημα με τα δεδομένα που επιχειρήσατε να εισαγάγετε. Παρακαλώ επιλύστε τα σφάλματα που αναφέρονται παρακάτω στο αρχείο προέλευσης και προσπαθήστε ξανά." @@ -3024,7 +3134,7 @@ "message": "Τα δεδομένα εισήχθησαν επιτυχώς" }, "importSuccessNumberOfItems": { - "message": "Ένα σύνολο $AMOUNT$ στοιχείων εισήχθησαν.", + "message": "Ένα σύνολο $AMOUNT$ αντικειμένων εισήχθησαν.", "placeholders": { "amount": { "content": "$1", @@ -3033,28 +3143,28 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Προσπαθήστε ξανά" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Απαιτείται επαλήθευση για αυτήν την ενέργεια. Ορίστε ένα PIN για να συνεχίσετε." }, "setPin": { - "message": "Set PIN" + "message": "Ορισμός PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Επαλήθευση με βιομετρικά" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Σε αναμονή επιβεβαίωσης" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Αδύνατη η ολοκλήρωση των βιομετρικών." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Χρειάζεστε μια διαφορετική μέθοδο;" }, "useMasterPassword": { - "message": "Use master password" + "message": "Χρήση κύριου κωδικού πρόσβασης" }, "usePin": { "message": "Χρήση PIN" @@ -3063,7 +3173,7 @@ "message": "Χρήση βιομετρικών" }, "enterVerificationCodeSentToEmail": { - "message": "Εισάγετε τον κωδικό επαλήθευσης που έχει σταλεί στο ηλεκτρονικό ταχυδρομείο σας." + "message": "Εισάγετε τον κωδικό επαλήθευσης που έχει σταλεί στο ηλ. ταχυδρομείο σας." }, "resendCode": { "message": "Επαναποστολή κωδικού" @@ -3081,19 +3191,19 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Σφάλμα κατά τη σύνδεση με την υπηρεσία Duo. Χρησιμοποιήστε μια διαφορετική μέθοδο σύνδεσης δύο βημάτων ή επικοινωνήστε με την Duo για βοήθεια." }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Εκκινήστε το Duo και ακολουθήστε τα βήματα για να ολοκληρώσετε τη σύνδεση." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Απαιτείται σύνδεση δύο βημάτων Duo για το λογαριασμό σας." }, "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." + "message": "Ανοίξτε την επέκταση σε νέο παράθυρο για να ολοκληρώσετε τη σύνδεση." }, "popoutExtension": { - "message": "Popout extension" + "message": "Άνοιγμα επέκτασης σε νέο παράθυρο" }, "launchDuo": { "message": "Εκκίνηση Duo" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Μη έγκυρος κωδικός πρόσβασης, παρακαλώ χρησιμοποιήστε τον κωδικό πρόσβασης που εισαγάγατε όταν δημιουργήσατε το αρχείο εξαγωγής." }, - "importDestination": { - "message": "Προορισμός εισαγωγής" + "destination": { + "message": "Προορισμός" }, "learnAboutImportOptions": { "message": "Μάθετε για τις επιλογές εισαγωγής σας" @@ -3136,7 +3246,7 @@ "message": "Το αρχείο περιέχει μη συσχετισμένα στοιχεία." }, "selectFormat": { - "message": "Επιλέξτε τη μορφή του αρχείου εισαγωγής" + "message": "Επιλέξτε τον τύπο του αρχείου εισαγωγής" }, "selectImportFile": { "message": "Επιλέξτε το αρχείο εισαγωγής" @@ -3161,7 +3271,7 @@ } }, "confirmVaultImport": { - "message": "Επιβεβαίωση εισαγωγής θησαυροφυλακίου" + "message": "Επιβεβαίωση εισαγωγής θησαυ/κίου" }, "confirmVaultImportDesc": { "message": "Αυτό το αρχείο προστατεύεται με κωδικό πρόσβασης. Παρακαλώ εισαγάγετε τον κωδικό πρόσβασης για την εισαγωγή δεδομένων." @@ -3230,7 +3340,7 @@ "message": "Δεν βρέθηκαν δεδομένα LastPass" }, "incorrectUsernameOrPassword": { - "message": "Λάθος όνομα χρήστη ή κωδικού πρόσβασης" + "message": "Λάθος όνομα χρήστη ή κωδικός πρόσβασης" }, "incorrectPassword": { "message": "Εσφαλμένος κωδικός πρόσβασης" @@ -3248,7 +3358,7 @@ "message": "Συμπερίληψη κοινόχρηστων φακέλων" }, "lastPassEmail": { - "message": "Διεύθυνση Αλληλογραφίας Lastpass" + "message": "Διεύθυνση ηλ. ταχυδρομείου LastPass" }, "importingYourAccount": { "message": "Εισαγωγή του λογαριασμού σας..." @@ -3288,7 +3398,7 @@ "message": "Εισαγωγή από CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Δοκιμάστε ξανά ή ψάξτε για ένα email από το LastPass για να επιβεβαιώσετε ότι είστε εσείς." + "message": "Δοκιμάστε ξανά ή ψάξτε για ένα μήνυμα ηλ. ταχυδρομείου από το LastPass για να επιβεβαιώσετε ότι είστε εσείς." }, "collection": { "message": "Συλλογή" @@ -3327,7 +3437,7 @@ "message": "διακομιστής" }, "hostedAt": { - "message": "hosted at" + "message": "φιλοξενούμενο σε" }, "useDeviceOrHardwareKey": { "message": "Χρήση της συσκευής ή του φυσικού κλειδιού σας" @@ -3339,11 +3449,11 @@ "message": "Πάντα για αυτήν την ιστοσελίδα" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ added to excluded domains.", + "message": "Το $DOMAIN$ προστέθηκε στους εξαιρούμενους τομείς.", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Κοινοί τύποι", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Συνεχίστε στις ρυθμίσεις περιηγητή;", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Συνέχεια στο Κέντρο Βοήθειας;", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Αλλάξτε τις ρυθμίσεις αυτόματης συμπλήρωσης και διαχείρισης κωδικών πρόσβασης του περιηγητή σας.", + "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": "Μπορείτε να δείτε και να ορίσετε συντομεύσεις επεκτάσεων στις ρυθμίσεις του περιηγητή σας.", + "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": "Αλλάξτε τις ρυθμίσεις αυτόματης συμπλήρωσης και διαχείρισης κωδικών πρόσβασης του περιηγητή σας.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Μπορείτε να δείτε και να ορίσετε συντομεύσεις επεκτάσεων στις ρυθμίσεις του περιηγητή σας.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Να γίνει το Bitwarden ο προεπιλεγμένος διαχειριστής κωδικών πρόσβασης σας;", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Η αγνόηση αυτής της επιλογής μπορεί να προκαλέσει συγκρούσεις μεταξύ του μενού αυτόματης συμπλήρωσης Bitwarden και του περιηγητή σας.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3412,7 +3546,7 @@ "message": "Καθαρισμός φίλτρων ή δοκιμή άλλου όρου αναζήτησης" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Αντιγραφή πληροφοριών - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -3422,7 +3556,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Αντιγραφή Σημείωσης - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -3432,7 +3566,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Περισσότερες επιλογές, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3442,7 +3576,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Περισσότερες επιλογές - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3452,7 +3586,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Προβολή αντικειμένου - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -3462,7 +3596,7 @@ } }, "autofillTitle": { - "message": "Auto-fill - $ITEMNAME$", + "message": "Αυτόματη συμπλήρωση - $ITEMNAME$", "description": "Title for a button that auto-fills a login item.", "placeholders": { "itemname": { @@ -3472,40 +3606,40 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "Δεν υπάρχουν τιμές για αντιγραφή" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Ανάθεση σε συλλογές" }, "copyEmail": { - "message": "Copy email" + "message": "Αντιγραφή διεύθυνσης ηλ. ταχυδρομείου" }, "copyPhone": { - "message": "Copy phone" + "message": "Αντιγραφή τηλεφώνου" }, "copyAddress": { - "message": "Copy address" + "message": "Αντιγραφή διεύθυνσης" }, "adminConsole": { - "message": "Admin Console" + "message": "Κονσόλα Διαχειριστή" }, "accountSecurity": { - "message": "Account security" + "message": "Ασφάλεια λογαριασμού" }, "notifications": { - "message": "Notifications" + "message": "Ειδοποιήσεις" }, "appearance": { - "message": "Appearance" + "message": "Εμφάνιση" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Σφάλμα κατά την ανάθεση συλλογής προορισμού." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Σφάλμα κατά την ανάθεση φακέλου προορισμού." }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Προβολή αντικειμένων στο $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -3515,7 +3649,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Επιστροφή στο $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -3525,10 +3659,10 @@ } }, "new": { - "message": "New" + "message": "Νέο" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Αφαίρεση $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -3538,16 +3672,16 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "Αντικείμενα χωρίς φάκελο" }, "itemDetails": { - "message": "Item details" + "message": "Λεπτομέρειες αντικειμένου" }, "itemName": { - "message": "Item name" + "message": "Όνομα αντικειμένου" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "Δεν μπορείτε να αφαιρέσετε συλλογές που έχουν μόνο δικαιώματα Προβολής: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -3556,47 +3690,47 @@ } }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "Ο οργανισμός απενεργοποιήθηκε" }, "owner": { - "message": "Owner" + "message": "Ιδιοκτήτης" }, "selfOwnershipLabel": { - "message": "You", + "message": "Εσείς", "description": "Used as a label to indicate that the user is the owner of an item." }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "Δεν είναι δυνατή η πρόσβαση αντικειμένων σε απενεργοποιημένους οργανισμούς. Επικοινωνήστε με τον ιδιοκτήτη του οργανισμού σας για βοήθεια." }, "additionalInformation": { - "message": "Additional information" + "message": "Επιπρόσθετες πληροφορίες" }, "itemHistory": { - "message": "Item history" + "message": "Ιστορικό αντικειμένων" }, "lastEdited": { - "message": "Last edited" + "message": "Τελευταία τροποποίηση" }, "ownerYou": { - "message": "Owner: You" + "message": "Ιδιοκτήτης: Εσείς" }, "linked": { - "message": "Linked" + "message": "Συνδεδεμένο" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Επιτυχής Αντιγραφή" }, "upload": { - "message": "Upload" + "message": "Μεταφόρτωση" }, "addAttachment": { - "message": "Add attachment" + "message": "Προσθήκη συνημμένου" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "Το μέγιστο μέγεθος αρχείου είναι 500 MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "Διαγραφή συνημμένου $NAME$", "placeholders": { "name": { "content": "$1", @@ -3605,7 +3739,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "Λήψη $NAME$", "placeholders": { "name": { "content": "$1", @@ -3614,28 +3748,28 @@ } }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "Είστε σίγουροι ότι θέλετε να διαγράψετε οριστικά αυτό το συνημμένο;" }, "premium": { "message": "Premium" }, "freeOrgsCannotUseAttachments": { - "message": "Free organizations cannot use attachments" + "message": "Οι δωρεάν οργανισμοί δεν μπορούν να χρησιμοποιήσουν συνημμένα" }, "filters": { - "message": "Filters" + "message": "Φίλτρα" }, "personalDetails": { - "message": "Personal details" + "message": "Προσωπικές πληροφορίες" }, "identification": { - "message": "Identification" + "message": "Ταυτοποίηση" }, "contactInfo": { - "message": "Contact info" + "message": "Στοιχεία επικοινωνίας" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "Λήψη - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Στοιχεία σύνδεσης" }, @@ -3667,11 +3805,17 @@ "loading": { "message": "Φόρτωση" }, + "data": { + "message": "Δεδομένα" + }, "assign": { "message": "Ανάθεση" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Μόνο τα μέλη του οργανισμού με πρόσβαση σε αυτές τις συλλογές θα είναι σε θέση να δουν τα αντικείμενα." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Μόνο μέλη του οργανισμού με πρόσβαση σε αυτές τις συλλογές θα είναι σε θέση να δουν τα αντικείμενα." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Μόνο μέλη του οργανισμού με πρόσβαση σε αυτές τις συλλογές θα είναι σε θέση να δουν τα αντικείμενα." }, "bulkCollectionAssignmentWarning": { "message": "Έχετε επιλέξει $TOTAL_COUNT$ αντικείμενα. Δεν μπορείτε να ενημερώσετε τα $READONLY_COUNT$ αντικείμενα επειδή δεν έχετε δικαιώματα επεξεργασίας.", @@ -3698,25 +3842,25 @@ "message": "Ετικέτα πεδίου" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Χρήση πεδίων κειμένου για δεδομένα όπως ερωτήσεις ασφαλείας" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Χρήση κρυφών πεδίων για ευαίσθητα δεδομένα όπως ένας κωδικός πρόσβασης" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to auto-fill a form's checkbox, like a remember email" + "message": "Χρησιμοποιήστε τα πλαίσια επιλογής αν θέλετε να συμπληρώνετε αυτόματα το πλαίσιο επιλογής μιας φόρμας, όπως αυτό της απομνημόνευσης διεύθυνσης ηλ. ταχυδρομείου" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing auto-fill issues for a specific website." + "message": "Χρησιμοποιήστε ένα συνδεδεμένο πεδίο όταν αντιμετωπίζετε προβλήματα αυτόματης συμπλήρωσης για μια συγκεκριμένη ιστοσελίδα." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "Εισάγετε το html id, name, aria-label, ή placeholder του πεδίου." }, "editField": { "message": "Επεξεργασία πεδίου" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "Επεξεργασία $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3725,7 +3869,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "Διαγραφή $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3734,7 +3878,7 @@ } }, "fieldAdded": { - "message": "$LABEL$ added", + "message": "$LABEL$ προστέθηκε", "placeholders": { "label": { "content": "$1", @@ -3743,7 +3887,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "Αναδιοργάνωση $LABEL$. Χρησιμοποιήστε τα βελάκια για τη μετακίνηση του αντικειμένου προς τα πάνω ή κάτω.", "placeholders": { "label": { "content": "$1", @@ -3752,7 +3896,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ μετακινήθηκε πάνω, θέση $INDEX$ από $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Επιλέξτε συλλογές για ανάθεση" }, - "personalItemsTransferWarning": { - "message": "Το $PERSONAL_ITEMS_COUNT$ θα μεταφερθεί μόνιμα στον επιλεγμένο οργανισμό. Δε θα κατέχετε πλέον αυτά τα αντικείμενα.", + "personalItemTransferWarningSingular": { + "message": "1 αντικείμενο θα μεταφερθεί μόνιμα στον επιλεγμένο οργανισμό. Δε θα κατέχετε πλέον αυτό το αντικείμενο." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ αντικείμενα θα μεταφερθούν μόνιμα στον επιλεγμένο οργανισμό. Δε θα κατέχετε πλέον αυτά τα αντικείμενα.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "Το $PERSONAL_ITEMS_COUNT$ θα μεταφερθεί μόνιμα στο $ORG$. Δε θα κατέχετε πλέον αυτά τα αντικείμενα.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 αντικείμενο θα μεταφερθεί μόνιμα στο $ORG$. Δε θα κατέχετε πλέον αυτό το αντικείμενο.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ αντικείμενα θα μεταφερθούν μόνιμα στο $ORG$. Δε θα κατέχετε πλέον αυτά τα αντικείμενα.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,8 +3964,26 @@ } } }, + "itemsMovedToOrg": { + "message": "Τα αντικείμενα μεταφέρθηκαν στο $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Το αντικείμενο μεταφέρθηκε στο $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ μετακινήθηκε κάνω, θέση $INDEX$ από $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Τοποθεσία Αντικειμένου" } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 96af6b92ed2..c13fe87c9d9 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organisation" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organisation by setting a master password." + }, "tab": { "message": "Tab" }, @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identities as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,7 +1242,16 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Enable Auto-fill on Page Load" }, "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, auto-fill when the web page loads." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit auto-fill on page load." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Learn more about auto-fill" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organisation policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Auto-fill keyboard shortcut" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Centre?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organisation members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organisation members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organisation. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organisation. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organisation. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index e79a8afece4..1522f8b13df 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organisation" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organisation by setting a master password." + }, "tab": { "message": "Tab" }, @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Added item" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "The \"add login notification\" automatically prompts you to save new logins to your vault whenever you log into them for the first time." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,7 +1242,16 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Enable auto-fill on page load" }, "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, automatically perform an auto-fill when the web page loads." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit auto-fill on page load." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Learn more about auto-fill" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organisation policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded Domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Auto-fill keyboard shortcut" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Centre?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,11 +3805,17 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organisation members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Only organisation members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organisation. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organisation. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index dfddc46ec87..31a54956523 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Identifícate o crea una nueva cuenta para acceder a tu caja fuerte." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Crear cuenta" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Pista de contraseña maestra (opcional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Pestaña" }, @@ -108,7 +117,7 @@ "message": "Copiar código de seguridad" }, "autoFill": { - "message": "Autorellenar" + "message": "Autorrellenar" }, "autoFillLogin": { "message": "Autocompletar inicio de sesión" @@ -736,6 +745,10 @@ "newUri": { "message": "Nueva URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Elemento añadido" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Pedir que se añada el inicio de sesión" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "La opción \"Notificación para añadir entradas\" pregunta automáticamente si quieres guardar nuevas entradas en tu caja fuerte cuando te identificas en un sitio web por primera vez." }, "addLoginNotificationDescAlt": { "message": "Pide que se agregue un elemento si no se encuentra uno en su caja fuerte. Se aplica a todas las cuentas que hayan iniciado sesión." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Mostrar las tarjetas en la pestaña" }, "showCardsCurrentTabDesc": { "message": "Listar los elementos de tarjetas en la página para facilitar el auto-rellenado." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Mostrar las identidades en la página" }, @@ -1220,8 +1242,17 @@ "message": "Mostrar menú de autocompletar en los campos del formulario", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Se aplica a todas las cuentas que hayan iniciado sesión." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Desactive la configuración del gestor de contraseñas del navegador para evitar conflictos." @@ -1241,15 +1272,34 @@ "message": "Cuando se seleccione el icono de relleno automático", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Habilitar autorrellenar al cargar la página" }, "enableAutoFillOnPageLoadDesc": { "message": "Si se detecta un formulario, realizar automáticamente un autorellenado cuando la web cargue." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Los sitios web vulnerados o no confiables pueden explotar el autorelleno al cargar la página." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Más información sobre el relleno automático" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Booleano" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Vinculado", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Una política organizacional ha bloqueado la importación de elementos a su caja fuerte personal." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Dominios excluidos" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden no pedirá que se guarden los datos de acceso para estos dominios en todas las sesiones iniciadas. Debe actualizar la página para que los cambios surtan efecto." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ no es un dominio válido", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protegido por contraseña" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copiar enlace Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Ajustes de autocompletar" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Atajo de teclado para autocompletar" }, @@ -2970,10 +3048,18 @@ "message": "Desbloquea tu cuenta para ver las entradas coincidentes", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Desbloquear la cuenta", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Rellenar credenciales para", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Añadir elemento de caja fuerte nuevo", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Menú de relleno automático de Bitwarden disponible. Presione ↓ para seleccionar.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Contraseña de archivo no válida. Por favor utilice la contraseña que introdujo cuando creó el archivo de exportación." }, - "importDestination": { - "message": "Importar destino" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Aprende sobre tus opciones de importación" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Formatos comunes", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "¿Hacer de Bitwarden su administrador de contraseñas predeterminado?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No hay valores para copiar" }, - "assignCollections": { - "message": "Asignar colecciones" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copiar correo electrónico" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Cargando" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index b22ffec37d8..b0a04c6c648 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Logi oma olemasolevasse kontosse sisse või loo uus konto." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Konto loomine" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Ülemparooli vihje (ei ole kohustuslik)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Kaart" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Uus URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Kirje on lisatud" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Küsi \"Lisa konto andmed\"" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "\"Lisa konto andmed\" teavitus ilmub pärast esimest sisselogimist ning võimaldab kontoandmeid automaatselt Bitwardenisse lisada." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Kuva \"Kaart\" vaates kaardiandmed" }, "showCardsCurrentTabDesc": { "message": "Kuvab \"Kaart\" vaates kaardiandmeid, et neid saaks kiiresti sisestada" }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Kuva \"Kaart\" vaates identiteete" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Luba kontoandmete täitmine" }, "enableAutoFillOnPageLoadDesc": { "message": "Sisselogimise vormi tuvastamisel sisestatakse sinna kontoandmed automaatselt." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Häkitud või ebausaldusväärsed veebilehed võivad lehe laadimisel automaatset sisestamist kuritarvitada." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Rohkem infot automaattäite kohta" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Ühenduses", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Väljajäetud domeenid" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ ei ole õige domeen.", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Parooliga kaitstud" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopeeri Sendi link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Automaattäite seaded" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Automaattäite klaviatuuri otseteed" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 96c807caac7..b933dd2b9e1 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Saioa hasi edo sortu kontu berri bat zure kutxa gotorrera sartzeko." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Sortu kontua" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Pasahitz nagusirako pista (aukerakoa)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Fitxak" }, @@ -736,6 +745,10 @@ "newUri": { "message": "URI berria" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Elementua gehituta" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Galdetu saio-hasiera gehitzeko" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Elementu bat gehitu nahi duzun galdetu, elementu hau zure kutxa gotorrean ez badago." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Erakutsi txartelak fitxa orrian" }, "showCardsCurrentTabDesc": { "message": "Erakutsi elementuen txartelak fitxa orrian, erraz auto-betetzeko." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Erakutsi identitateak fitxa orrian" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,17 +1272,36 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Auto-bete orrialdea kargatzean" }, "enableAutoFillOnPageLoadDesc": { "message": "Saio-hasierako formulario bat detektatzen bada, auto-bete webgunea kargatzen denean." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Saio-hasierako elementuetarako lehenetsitako auto-betetzearen konfigurazioa" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolearra" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Lotuta", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Kanporatutako domeinuak" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ ez da onartutako domeinu bat", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Pasahitz babestua" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send esteka kopiatu", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 7c232bcd8bc..961e4408e44 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -7,12 +7,15 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "message": "در خانه، محل کار و هر کجای دیگر، Bitwarden به راحتی همه‌ رمزها و کلیدهای عبور، و اطلاعات حساس شما را ایمن می‌کند", "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "وارد شوید یا یک حساب کاربری بسازید تا به گاوصندوق امن‌تان دسترسی یابید." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "ایجاد حساب کاربری" }, @@ -20,7 +23,7 @@ "message": "تنظیم رمز عبور قوی" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "ایجاد حساب خود را با تنظیم رمز عبور تکمیل کنید" }, "login": { "message": "ورود" @@ -68,6 +71,12 @@ "masterPassHint": { "message": "یادآور کلمه عبور اصلی (اختیاری)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "زبانه" }, @@ -192,19 +201,19 @@ "message": "Continue to web app?" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "ویژگی‌های بیشتر حساب Bitwarden خود را در برنامه وب کاوش کنید." }, "continueToHelpCenter": { "message": "Continue to Help Center?" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "درباره استفاده از Bitwarden در مرکز راهنما بیشتر بیاموزید." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "آیا میخواهید به فروشگاه افزونه مرورگر ادامه دهید?" }, "continueToBrowserExtensionStoreDesc": { - "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." + "message": "به دیگران کمک کنید تا بفهمند آیا Bitwarden برایشان مناسب است یا نه. به فروشگاه افزونه مرورگر خود بروید و نظر خود را به اشتراک بگذارید." }, "changeMasterPasswordOnWebConfirmation": { "message": "You can change your master password on the Bitwarden web app." @@ -736,6 +745,10 @@ "newUri": { "message": "نشانی اینترنتی جدید" }, + "addDomain": { + "message": "افزودن دامنه", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "مورد اضافه شد" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "درخواست افزودن ورود به سیستم" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "در صورتی که موردی در گاوصندوق شما یافت نشد، درخواست افزودن کنید." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "نمایش کارت‌ها در صفحه برگه" }, "showCardsCurrentTabDesc": { "message": "برای پر کردن خودکار آسان، موارد کارت را در صفحه برگه فهرست کن." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "نشان دادن هویت در صفحه برگه" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "ویرایش تنظیمات مرورگر." @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "پر کردن خودکار هنگام بارگذاری صفحه" }, "enableAutoFillOnPageLoadDesc": { "message": "اگر یک فرم ورودی شناسایی شد، وقتی صفحه وب بارگذاری شد، به صورت خودکار پر شود." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "وب‌سایت‌های در معرض خطر یا نامعتبر می‌توانند از پر کردن خودکار در بارگذاری صفحه سوء استفاده کنند." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "درباره پر کردن خودکار بیشتر بدانید" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "منطقی" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "پیوند شده", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "دامنه های مستثنی" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ دامنه معتبری نیست", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "ارسال", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "محافظت ‌شده با کلمه عبور" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "پیوند ارسال را کپی کن", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "تنظیمات پر کردن خودکار" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "میانبر صفحه کلید پر کردن خودکار" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "افزودن موردی جدید به گاوصندوق", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index a4181253102..7552425f827 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Käytä salattua holviasi kirjautumalla sisään tai luo uusi tili." }, + "inviteAccepted": { + "message": "Kutsu hyväksyttiin" + }, "createAccount": { "message": "Luo tili" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Pääsalasanan vihje (valinnainen)" }, + "joinOrganization": { + "message": "Liity organisaatioon" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Viimeistele organisaatioon liittyminen asettamalla pääsalasana." + }, "tab": { "message": "Välilehti" }, @@ -242,7 +251,7 @@ "message": "Bitwarden Authenticator" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticatorin avulla voit säilyttää todennusavaimet ja luoda TOTP-koodeja kaksivaiheista tunnistautumista varten. Lue lisää bitwarden.com-sivustolta." + "message": "Bitwarden Authenticatorin avulla voit säilyttää todennusavaimet ja luoda TOTP-koodeja kaksivaiheista kirjautumista varten. Lue lisää bitwarden.com-sivustolta." }, "bitwardenSecretsManager": { "message": "Bitwarden Salaisuushallinta" @@ -612,7 +621,7 @@ "message": "Todennuskoodi vaaditaan." }, "webauthnCancelOrTimeout": { - "message": "Todennus peruutettiin tai siinä kesti liian kauan. Yritä uudelleen." + "message": "Tunnistautuminen peruttiin tai se kesti liian kauan. Yritä uudelleen." }, "invalidVerificationCode": { "message": "Virheellinen todennuskoodi" @@ -640,13 +649,13 @@ "message": "Skannaa todennusavaimen QR-koodi nykyiseltä verkkosivulta" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Tee kaksivaiheisesta kirjautumisesta saumatonta" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden voi säilyttää ja täyttää kaksivaiheisen kirjautumisen koodit. Kopioi ja liitä todennusavain tähän kenttään." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden voi säilyttää ja täyttää kaksivaiheisen kirjautumisen koodit. Kamerakuvakkeella voit kaapata todennusavaimen avoimen sivun QR-koodista automaattisesti, tai voit kopioida ja liittää sen tähän kenttään manuaalisesti." }, "copyTOTP": { "message": "Kopioi todennusavain (TOTP)" @@ -661,19 +670,19 @@ "message": "Kirjautumisistuntosi on erääntynyt." }, "logIn": { - "message": "Log in" + "message": "Kirjaudu" }, "restartRegistration": { - "message": "Restart registration" + "message": "Aloita rekisteröityminen alusta" }, "expiredLink": { - "message": "Expired link" + "message": "Vanhentunut linkki" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Aloita rekisteröityminen alusta tai yritä kirjautua sisään uudelleen." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Sinulla saattaa olla jo tili" }, "logOutConfirmation": { "message": "Haluatko varmasti kirjautua ulos?" @@ -736,6 +745,10 @@ "newUri": { "message": "Uusi URI" }, + "addDomain": { + "message": "Lisää verkkotunnus", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Kohde lisättiin" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Kysy lisätäänkö kirjautumistieto" }, + "vaultSaveOptionsTitle": { + "message": "Holvitallennuksen valinnat" + }, "addLoginNotificationDesc": { "message": "Kysy lisätäänkö uusi kohde, jos holvissa ei vielä ole sopivaa kohdetta." }, "addLoginNotificationDescAlt": { "message": "Ehdota kohteen tallennusta, jos holvistasi ei vielä löydy vastaavaa kohdetta. Koskee kaikkia kirjautuneita tilejä." }, + "showCardsInVaultView": { + "message": "Näytä kortit automaattitäytön ehdotuksina Holvit-näkymässä" + }, "showCardsCurrentTab": { "message": "Näytä kortit välilehtiosiossa" }, "showCardsCurrentTabDesc": { "message": "Kortit näytetään laajennuksen välilehtisivulla niiden automaattisen täytön helpottamiseksi." }, + "showIdentitiesInVaultView": { + "message": "Näytä identiteetit automaattitäytön ehdotuksina Holvit-näkymässä" + }, "showIdentitiesCurrentTab": { "message": "Näytä henkilöllisyydet välilehtiosiossa" }, @@ -1067,7 +1089,7 @@ "message": "Kopioi TOTP-koodi automaattisesti" }, "disableAutoTotpCopyDesc": { - "message": "Jos kirjautumistieto sisältää kaksivaiheisen todennuksen avaimen, kopioidaan TOTP-todennuskoodi leikepöydälle kohteen automaattisen täytön yhteydessä." + "message": "Jos kirjautumistieto sisältää kaksivaiheisen kirjautumisen todennusavaimen, kopioidaan TOTP-koodi leikepöydälle kohteen automaattisen täytön yhteydessä." }, "enableAutoBiometricsPrompt": { "message": "Pyydä Biometristä todennusta käynnistettäessä" @@ -1106,7 +1128,7 @@ "message": "Lähetä todennuskoodi sähköpostitse uudelleen" }, "useAnotherTwoStepMethod": { - "message": "Käytä toista kaksivaiheisen kirjautumisen todentajaa" + "message": "Käytä vaihtoehtoista todennustapaa" }, "insertYubiKey": { "message": "Kytke YubiKey-todennuslaitteesi tietokoneen USB-porttiin ja paina sen painiketta." @@ -1115,7 +1137,7 @@ "message": "Kytke todennuslaitteesi tietokoneen USB-porttiin. Jos laitteessa on painike, paina sitä." }, "webAuthnNewTab": { - "message": "Aloittaaksesi kaksivaiheisen WebAuthn-todennuksen, seuraa alla olevasta painikkeesta uuteen välilehteen avautuvia ohjeita." + "message": "Aloittaaksesi kaksivaiheisen WebAuthn-tunnistautumisen, seuraa alla olevasta painikkeesta uuteen välilehteen avautuvia ohjeita." }, "webAuthnNewTabOpen": { "message": "Avaa uusi välilehti" @@ -1220,7 +1242,16 @@ "message": "Näytä automaattitäytön valikko lomakekentissä", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Automaattitäytön ehdotukset" + }, + "showInlineMenuLabel": { + "message": "Näytä automaattitäytön ehdotukset lomakekentissä" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Näytä ehdotukset, kun kuvake on valittu" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Koskee kaikkia kirjautuneita tilejä." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Kun automaattitäytön kuvaketta painetaan", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Automaattitäyttö sivun avautuessa" + }, "enableAutoFillOnPageLoad": { "message": "Automaattitäyttö sivun avautuessa" }, "enableAutoFillOnPageLoadDesc": { "message": "Automaattinen täyttö suoritetaan sivun avautuessa, jos sivulla havaitaan kirjautumislomake." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Varoitus:$CLOSETAG$ Vaarantuneet tai epäluotettavat verkkosivustot voivat hyväksikäyttää automaattitäyttöä sivun latauksen yhteydessä.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Vaarantuneet tai epäluotettavat sivustot voivat väärinkäyttää sivun avautuessa suoritettavaa automaattista täyttöä." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Lue lisää riskeistä" + }, "learnMoreAboutAutofill": { "message": "Lisätietoja automaattitäytöstä" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Totuusarvo" }, + "cfTypeCheckbox": { + "message": "Valintaruutu" + }, "cfTypeLinked": { "message": "Linkitetty", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1758,7 +1811,7 @@ "message": "Onko sinulla jo tili?" }, "vaultTimeoutLogOutConfirmation": { - "message": "Uloskirjautuminen estää pääsyn holviisi ja vaatii ajan umpeuduttua todennuksen Internet-yhteyden välityksellä. Haluatko varmasti käyttää asetusta?" + "message": "Uloskirjautuminen estää pääsyn holviisi ja vaatii ajan umpeuduttua tunnistautumisen Internet-yhteyden välityksellä. Haluatko varmasti käyttää asetusta?" }, "vaultTimeoutLogOutConfirmationTitle": { "message": "Aikakatkaisutoiminnon vahvistus" @@ -1848,7 +1901,7 @@ "message": "Uusi pääsalasanasi ei täytä käytännön määrittämiä vaatimuksia." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Vastaanota Bitwardenilta postilaatikkoosi vinkkejä, uutisia ja tutkimusmahdollisuuksia." }, "unsubscribe": { "message": "Lopeta tilaus" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Organisaatiokäytäntö estää kohteiden tuonnin yksityiseen holviisi." }, + "domainsTitle": { + "message": "Verkkotunnukset", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Ohitettavat verkkotunnukset" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden ei pyydä kirjautumistietojen tallennusta näillä verkkotunnuksilla. Koskee kaikkia kirjautuneita tilejä. Ota muutokset käyttöön päivittämällä sivu." }, + "websiteItemLabel": { + "message": "Verkkotunnus $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ ei ole kelvollinen verkkotunnus", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Rajoitettujen verkkotunnusten muutokset tallennettiin" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Salasanasuojattu" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopioi Send-linkki", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Automaattitäytön asetukset" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Automaattitäyttö-pikakuvake" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Muuta pikakuvaketta" + }, "autofillShortcut": { "message": "Automaattitäytön pikanäppäin" }, @@ -2970,10 +3048,18 @@ "message": "Näytä sopivat kirjautumistiedot avaamalla tilisi lukitus", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Avaa tili", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Täytä kirjautumistiedot kohteesta", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Lisää holviin uusi kohde", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwardenin automaattisen täytön valikko on käytettävissä. Valitse painamalla alas-nuolinäppäintä.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3081,7 +3191,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Virhe yhdistettäessä Duo-palveluun. Käytä toista kaksivaiheista kirjautumismenetelmää tai ota yhteyttä Duoon saadaksesi apua." + "message": "Virhe yhdistettäessä Duo-palveluun. Käytä vaihtoehtoista todennustapaa tai ole yhteydessä Duon asiakaspalveluun saadaksesi apua." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Tiedoston salasana on virheellinen. Käytä vientitiedoston luonnin yhteydessä syötettyä salasanaa." }, - "importDestination": { - "message": "Tuontikohde" + "destination": { + "message": "Kohde" }, "learnAboutImportOptions": { "message": "Lue lisää tuontivaihtoehdoista" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Yleiset muodot", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Avataanko selaimen asetukset?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Avataanko tukikeskus?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Muuta selaimesi automaattitäytön ja salasananhallinnan asetuksia.", + "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": "Voit tarkastella ja asettaa laajennusten pikakuvakkeita selaimesi asetuksissa.", + "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": "Muuta selaimesi automaattitäytön ja salasananhallinnan asetuksia.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Voit tarkastella ja asettaa laajennusten pikakuvakkeita selaimesi asetuksissa.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Määritetäänkö Bitwarden oletusarvoiseksi salasanahallinnaksi?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Ei kopioitavia arvoja" }, - "assignCollections": { - "message": "Määritä kokoelmat" + "assignToCollections": { + "message": "Määritä kokoelmiin" }, "copyEmail": { "message": "Kopioi sähköpostiosoite" @@ -3569,10 +3703,10 @@ "message": "Käytöstä poistettujen organisaatioiden kohteet eivät ole käytettävissä. Ole yhteydessä organisaation omistajaan saadaksesi apua." }, "additionalInformation": { - "message": "Lisätietoja" + "message": "Lisätiedot" }, "itemHistory": { - "message": "Kohdehistoria" + "message": "Kohteen historia" }, "lastEdited": { "message": "Viimeksi muokattu" @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "Kirjautumistiedot" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Todennusavain" }, "cardDetails": { "message": "Kortin tiedot" @@ -3667,14 +3805,20 @@ "loading": { "message": "Ladataan" }, - "assign": { - "message": "Assign" + "data": { + "message": "Tiedot" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "assign": { + "message": "Määritä" + }, + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Vain näiden kokoelmien käyttöoikeuden omaavat organisaation jäsenet voivat nähdä kohteen." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Vain näiden kokoelmien käyttöoikeuden omaavat organisaation jäsenet voivat nähdä kohteet." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Olet valinnut $TOTAL_COUNT$ kohdetta. Näistä $READONLY_COUNT$ et voi muuttaa, koska käyttöoikeutesi eivät salli muokkausta.", "placeholders": { "total_count": { "content": "$1", @@ -3695,28 +3839,28 @@ "message": "Kentän tyyppi" }, "fieldLabel": { - "message": "Kentän otsikko" + "message": "Kentän nimi" }, "textHelpText": { - "message": "Käytä tekstikenttiä tiedoille, kuten turvakysymyksille" + "message": "Käytä tekstikenttiä esimerkiksi turvakysymysten kaltaisille tiedoille." }, "hiddenHelpText": { - "message": "Käytä piilotettuja kenttiä arkaluonteisille tiedoille, kuten salasanoille" + "message": "Käytä piilotettuja kenttiä esimerkiksi salasanojen kaltaisille arkaluonteisille tiedoille." }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to auto-fill a form's checkbox, like a remember email" + "message": "Käytä valintaruutuja esimerkiksi sähköpostiosoitteen muistamisen kaltaisten valintaruutujen automaattiseen merkintään." }, "linkedHelpText": { - "message": "Käytä linkitettyä kenttää, kun sinulla on automaattitäyttämiseen liittyviä ongelmia tietyllä verkkosivustolla." + "message": "Käytä linkitettyjä kenttiä kohdatessasi sivustokohtaisia automaattitäytön ongelmia." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "Syötä kentän HTML-koodista löytyvä id-, name-, aria-label- tai placeholder-arvo." }, "editField": { "message": "Muokkaa kenttää" }, "editFieldLabel": { - "message": "Muokkaa $LABEL$", + "message": "Muokkaa kohdetta $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3743,7 +3887,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "Siirrä $LABEL$. Liikuta kohdetta ylös- tai alaspäin nuolinäppäimillä.", "placeholders": { "label": { "content": "$1", @@ -3752,7 +3896,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ siirrettiin ylös, sijainti: $INDEX$ / $LENGTH$", + "message": "$LABEL$ siirrettiin ylemmäs, sijainti: $INDEX$/$LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3769,23 +3913,35 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Valitse määritettävät kokoelmat" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 kohde siirretään pysyvästi valitulle organisaatiolle, jonka jälkeen et enää omista sitä." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ kohdetta siirretään pysyvästi valitulle organisaatiolle, jonka jälkeen et enää omista niitä.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 kohde siirretään pysyvästi organisaatiolle $ORG$, jonka jälkeen et enää omista sitä.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ kohdetta siirretään pysyvästi organisaatiolle $ORG$, jonka jälkeen et enää omista niitä.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3794,13 +3950,31 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Kokoelmat määritettiin" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Et ole valinnut mitään." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Valitut kohteet siirrettiin organisaatiolle $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemsMovedToOrg": { + "message": "Kohteet siirrettiin organisaatioon $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Kohde siirrettiin organisaatioon $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3809,7 +3983,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ siirrettiin alas, sijainti: $INDEX$ / $LENGTH$", + "message": "$LABEL$ siirrettiin alemmas, sijainti: $INDEX$/$LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Kohteen sijainti" } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 3009e136842..a289d9bcab2 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Maglog-in o gumawa ng bagong account para ma-access ang iyong ligtas na kahadeyero." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Gumawa ng Account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Mungkahi sa Master Password (opsyonal)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Bagong URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Ang item ay idinagdag" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Tanungin na magdagdag ng login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Tanungin na magdagdag ng isang item kung wala itong nakita sa iyong vault." }, "addLoginNotificationDescAlt": { "message": "Hilingin na magdagdag ng isang item kung ang isa ay hindi mahanap sa iyong vault. Nalalapat sa lahat ng naka-log in na account." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Ipakita ang mga card sa Tab page" }, "showCardsCurrentTabDesc": { "message": "Itala ang mga item ng card sa Tab page para sa madaling auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Ipakita ang mga pagkatao sa Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Awtomatikong punan sa pagkarga ng pahina" }, "enableAutoFillOnPageLoadDesc": { "message": "Kung natukoy ang isang form sa pag login, awtomatikong punan kapag naglo load ang web page." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Ang mga nakompromiso o hindi pinagkakatiwalaang mga website ay maaaring samantalahin ang awtomatikong pagpuno sa pag load ng pahina." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Matuto nang higit pa tungkol sa auto fill" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Nilikha", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Hinarang ng isang patakaran ng organisasyon ang pag-import ng mga item sa iyong vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Inilayo na Domain" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ ay hindi isang valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Ipadala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protektado ng Password" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopyahin ang Link ng Padala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Mga setting ng auto-fill" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Keyboard shortcut para sa auto-fill" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 24e04825f74..7827e334bd1 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Identifiez-vous ou créez un nouveau compte pour accéder à votre coffre sécurisé." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Créer un compte" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Indice du mot de passe principal (facultatif)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Onglet" }, @@ -557,16 +566,16 @@ "message": "Sécurité" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "Confirmer le mot de passe principal" }, "masterPassword": { - "message": "Master password" + "message": "Mot de passe principal" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "Votre mot de passe principal ne peut pas être récupéré si vous l'oubliez !" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "Indice du mot de passe principal" }, "errorOccurred": { "message": "Une erreur est survenue" @@ -612,7 +621,7 @@ "message": "Le code de vérification est requis." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "L'authentification a été annulée ou a pris trop de temps. Veuillez réessayer." }, "invalidVerificationCode": { "message": "Code de vérification invalide" @@ -640,13 +649,13 @@ "message": "Scanner le QR code de l'authentificateur à partir de la page web actuelle" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Rendre la vérification en deux étapes transparente" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden peut stocker et remplir des codes de vérification en 2 étapes. Copiez et collez la clé dans ce champ." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden peut stocker et remplir des codes de vérification en 2 étapes. Sélectionnez l'icône caméra pour prendre une capture d'écran du code QR de l'authentificateur de ce site Web, ou copiez et collez la clé dans ce champ." }, "copyTOTP": { "message": "Copier la clé Authenticator (TOTP)" @@ -661,19 +670,19 @@ "message": "Votre session a expiré." }, "logIn": { - "message": "Log in" + "message": "Se connecter" }, "restartRegistration": { - "message": "Restart registration" + "message": "Redémarrer l'inscription" }, "expiredLink": { - "message": "Expired link" + "message": "Lien expiré" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Veuillez redémarrer votre inscription ou essayez de vous connecter." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Vous avez peut-être déjà un compte" }, "logOutConfirmation": { "message": "Êtes-vous sûr de vouloir vous déconnecter ?" @@ -736,6 +745,10 @@ "newUri": { "message": "Nouvel URI" }, + "addDomain": { + "message": "Ajouter un domaine", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Élément ajouté" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Demander d'ajouter un identifiant" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Demander d'ajouter un élément si aucun n'est trouvé dans votre coffre." }, "addLoginNotificationDescAlt": { "message": "Demande l'ajout d'un élément si celui-ci n'est pas trouvé dans votre coffre. S'applique à tous les comptes connectés." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Afficher les cartes de paiement sur la Page d'onglet" }, "showCardsCurrentTabDesc": { "message": "Liste les éléments des cartes de paiement sur la Page d'onglet pour faciliter la saisie automatique." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Afficher les identités sur la Page d'onglet" }, @@ -1220,8 +1242,17 @@ "message": "Afficher le menu de saisie automatique dans les champs d'un formulaire", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "S'applique à tous les comptes connectés." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Désactivez les paramètres du gestionnaire de mots de passe intégré à votre navigateur pour éviter les conflits." @@ -1241,15 +1272,34 @@ "message": "Lorsque l'icône de saisie automatique est sélectionnée", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Saisir automatiquement au chargement de la page" }, "enableAutoFillOnPageLoadDesc": { "message": "Si un formulaire de connexion est détecté, il sera saisi automatiquement lors du chargement de la page web." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "les sites web compromis ou non fiables peuvent exploiter la saisie automatique au chargement de la page." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "En savoir plus sur la saisie automatique" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Booléen" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Lié", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Une politique d'organisation a bloqué l'import d'éléments dans votre coffre personel." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Domaines exclus" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden ne demandera pas d'enregistrer les détails de connexion pour ces domaines pour tous les comptes connectés. Vous devez actualiser la page pour que les modifications prennent effet." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ n'est pas un domaine valide", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protégé par un mot de passe" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copier le lien du Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Paramètres de saisie automatique" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Raccourci clavier de saisie automatique" }, @@ -2970,10 +3048,18 @@ "message": "Déverrouillez votre compte pour afficher les identifiants correspondants", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Déverrouiller le compte", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Remplir les identifiants pour", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Ajouter un nouvel élément de coffre", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Menu de saisie automatique de Bitwarden disponible. Appuyez sur la touche Flèche bas pour sélectionner.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Mot de passe du fichier incorrect, veuillez utiliser le mot de passe saisi lors de l'exportation du fichier." }, - "importDestination": { - "message": "Importer la destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "En savoir plus sur vos options d'importation" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Formats communs", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Faire de Bitwarden votre gestionnaire de mots de passe par défaut ?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Aucune valeur à copier" }, - "assignCollections": { - "message": "Assigner une collection" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copier l'email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 13f59f958e2..6808b7a3085 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Rexístrate ou crea unha nova conta para acceder á túa caixa forte." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Crea unha conta" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Pista do contrasinal mestre (opcional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Separador" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Nova URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Elemento engadido" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Solicita engadir inicio de sesión" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Amosar tarxetas no separador" }, "showCardsCurrentTabDesc": { "message": "Lista os elementos de tarxeta no separador para fácil auto-completado." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Mostrar identidades no separador" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Booleano" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Vinculado", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copiar ligazón Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index d85872bbee5..b1d473fb145 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "צור חשבון חדש או התחבר כדי לגשת לכספת המאובטחת שלך." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "צור חשבון" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "רמז לסיסמה ראשית (אופציונאלי)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "לשונית" }, @@ -736,6 +745,10 @@ "newUri": { "message": "כתובת חדשה" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "פריט שהתווסף" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "ההודעה \"שמור פרטי כניסה\" מופיעה בכל פעם שתכנס לאתר חדש בפעם הראשונה." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,17 +1272,36 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "הפעל השלמה אוטומטית בזמן טעינת העמוד" }, "enableAutoFillOnPageLoadDesc": { "message": "אם זוהה טופס כניסה, בצע אוטומטית מילוי-אוטומטי כשהעמוד נטען." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "הגדרת ברירת מחדל למילוי אוטומטי של פרטי התחברות" @@ -1269,7 +1319,7 @@ "message": "מילוי אוטומטי אחרי טעינת דפים" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "פתיחת כספת בחלונית צפה" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "אמת או שקר" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "מקושר", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "יעד ייבוא" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "תסדירים נפוצים", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 0e7fd3bd9ae..23e70cc782d 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "अपनी सुरक्षित तिजोरी में प्रवेश करने के लिए नया खाता बनाएं या लॉग इन करें।" }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create Account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master Password Hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "टैब" }, @@ -736,6 +745,10 @@ "newUri": { "message": "नया URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "जोड़ा गया आइटम" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "लॉगिन जोड़ने के लिए कहें" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "The \"Add Login Notification\" automatically prompts you to save new logins to your vault whenever you log into them for the first time." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "टैब पेज पर कार्ड दिखाएं" }, "showCardsCurrentTabDesc": { "message": "आसान ऑटो-फिल के लिए टैब पेज पर कार्ड आइटम सूचीबद्ध करें।" }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "टैब पेज पर पहचान दिखाएं" }, @@ -1220,7 +1242,16 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,17 +1272,36 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Enable Auto-fill On Page Load." }, "enableAutoFillOnPageLoadDesc": { "message": "यदि लॉगिन फॉर्म का पता चलता है, तो वेब पेज लोड होने पर स्वचालित रूप से ऑटो-फिल करें।" }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "लॉगिन आइटम के लिए डिफ़ॉल्ट ऑटोफिल सेटिंग" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "बूलियन" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "जुड़ा हुआ", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "बहिष्कृत डोमेन" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "भेजें", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "पासवर्ड सुरक्षित है" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "कॉपी Send लिंक", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 74853546ee0..4c2111481f2 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Prijavi se ili stvori novi račun za pristup svojem sigurnom trezoru." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Stvori račun" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Podsjetnik glavne lozinke (neobavezno)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Kartica" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Novi URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Stavka dodana" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Upitaj za dodavanje prijave" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Upit za dodavanje prijave pojavljuje se kada se otkrije prva prijava na neko web mjesto. Bitwarden će te pitatati želiš li uneseno korisničko ime i lozinku spremiti u svoj trezor." }, "addLoginNotificationDescAlt": { "message": "Pitaj za dodavanje stavke ako nije pronađena u tvojem trezoru. Primjenjuje se na sve prijavljene račune." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Prikaži platne kartice" }, "showCardsCurrentTabDesc": { "message": "Prikazuj platne kartice za jednostavnu auto-ispunu." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Prikaži identitete" }, @@ -1220,8 +1242,17 @@ "message": "Prikaži izbornik za auto-ispunu u poljima obrasca", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Primjenjuje se na sve prijavljene račune." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Isključite postavke upravitelja zaporki ugrađene u preglednik kako biste izbjegli sukobe." @@ -1241,15 +1272,34 @@ "message": "Kada je odabrana ikona auto-ispune", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Auto-ispuna kod učitavanja" }, "enableAutoFillOnPageLoadDesc": { "message": "Nakon učitavanja web stranice, ako je otkriven obrazac za prijavu, auto-ispuni." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Ugrožene ili nepouzdane web stranice mogu iskoristiti auto-ispunu prilikom učitavanja stranice." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Saznaj više o auto-ispuni" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Povezano", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Organizacijsko pravilo onemogućuje uvoz stavki u tvoj osobni trezor." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Izuzete domene" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden neće tražiti spremanje podataka za prijavu za ove domene za sve prijavljene račune. Moraš osvježiti stranicu kako bi promjene stupile na snagu." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ nije valjana domena", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Zaštićeno lozinkom" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopiraj vezu na Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Postavke auto-ispune" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Tipkovnički precač auto-ispune" }, @@ -2970,10 +3048,18 @@ "message": "Otklučaj svoj račun za prikaz podudarnih prijava", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Otključaj račun", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Unesi vjerodajnice za", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Dodaj novu stavku trezora", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Dostupan je Bitwarden izbornik auto-ispune. Pritisni tipku sa strelicom prema dolje za odabir.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Nesipravna lozinka datoteke. Unesi lozinku izvozne datoteke." }, - "importDestination": { - "message": "Odredište uvoza" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Više o mogućnostima uvoza" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index dd1627f57a8..c9ad9bb0b1a 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Bejelentkezés vagy új fiók létrehozása a biztonsági széf eléréséhez." }, + "inviteAccepted": { + "message": "A meghívás elfogadásra került." + }, "createAccount": { "message": "Fiók létrehozása" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Mesterjelszó emlékeztető (nem kötelező)" }, + "joinOrganization": { + "message": "Csatlakozás szervezethez" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Fejezzük be a szervezethez csatlakozást egy mesterjelszó beállításával." + }, "tab": { "message": "Fül" }, @@ -640,13 +649,13 @@ "message": "Hitelesítő QR kód szkennelése az aktuális weboldalról" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Tegyük zökkenőmentessé a kétlépcsős azonosítást." }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "A Bitwarden képes tárolni és kitölteni a kétlépcsős ellenőrző kódokat. Másoljuk ki és illesszük be a kulcsot ebbe a mezőbe." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "A Bitwarden képes tárolni és kitölteni a kétlépcsős ellenőrző kódokat. Válasszuk a kamera ikont, hogy képernyőképet készítsünk a webhely hitelesítő QR kódjáról vagy másoljuk ki és illesszük be a kulcsot ebbe a mezőbe." }, "copyTOTP": { "message": "Hitelesítő kód másolása (TOTP)" @@ -736,6 +745,10 @@ "newUri": { "message": "Új URI" }, + "addDomain": { + "message": "Tartomány hozzáadása", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Az elem hozzáadásra került." }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Bejelentkezés hozzáadás kérése" }, + "vaultSaveOptionsTitle": { + "message": "Mentés széf opciókba" + }, "addLoginNotificationDesc": { "message": "A \"Bejelentkezés értesítés hozzáadása\" automatikusan felajánlja a bejelentkezés széfbe mentését az első bejelentkezéskor." }, "addLoginNotificationDescAlt": { "message": "Egy elem hozzáadásának kérése, ha az nem található a széfben. Minden bejelentkezett fiókra vonatkozik." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Kártyák megjelenítése a Fül oldalon" }, "showCardsCurrentTabDesc": { "message": "Kártyaelemek listázása a Fül oldalon a könnyű automatikus kitöltéshez." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Azonosítások megjelenítése a Fül oldalon" }, @@ -1220,8 +1242,17 @@ "message": "Automatikus kitöltés menü megjelenítése az űrlapmezőkön", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Minden bejelentkezett fiókra vonatkozik." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Az ütközések elkerülése érdekében kapcsoljuk ki a böngésző beépített jelszókezelő beállításait." @@ -1241,15 +1272,34 @@ "message": "Ha az automatikus kitöltés menü került kiválasztásra", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Automatikus kitöltés oldalbetöltésnél" + "message": "Automatikus kitöltés engedélyezése oldal betöltéskor" }, "enableAutoFillOnPageLoadDesc": { "message": "Ha egy bejelentkezési űrlap észlelésre került, az adatok automatikus kitöltése az oldal betöltésekor." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Az oldalbetöltésnél automatikus kitöltést a feltört vagy nem megbízhatató weboldalak kihasználhatják." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "További információk az automatikus kitöltésről" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean (Logikai)" }, + "cfTypeCheckbox": { + "message": "Jelölődoboz" + }, "cfTypeLinked": { "message": "Csatolva", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "A szervezeti politika blokkolta az elemek importálását az egyedi széfbe." }, + "domainsTitle": { + "message": "Tartomány", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Kizárt domainek" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "A Bitwarden nem kéri a bejelentkezési adatok mentését ezeknél a tartományoknál az összes bejelentkezési fiókra vonatkozva. A változtatások életbe lépéséhez frissíteni kell az oldalt." }, + "websiteItemLabel": { + "message": "Webhely $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ nem érvényes domain.", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "A kizárt tartomány módosítások mentésre kerültek." + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Jelszóval védett" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send hivatkozás másolása", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Automatikus kitöltés beállítások" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Automatikus kitöltés billentyűparancs" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Fiók feloldása", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Töltse kia hitelesítő adatokat", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Elem hozzáadása", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "A fájl jelszó érvénytelen. Használjuk az exportfájl létrehozásakor megadott jelszót." }, - "importDestination": { - "message": "Importálás leírás" + "destination": { + "message": "Cél" }, "learnAboutImportOptions": { "message": "Információ az importálási opciókról" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Általános formátumok", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Legyen a Bitwarden az alapértelmezett jelszókezelő?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Nincsenek másolandó értékek." }, - "assignCollections": { - "message": "Gyűjtemények hozzárendelése" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Email cím másolása" @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "Bejelentkezési hitelesítések" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Hitelesítő kulcs" }, "cardDetails": { "message": "Kártyaadatok" @@ -3667,11 +3805,17 @@ "loading": { "message": "A betöltés folyamatban van." }, + "data": { + "message": "Adat" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Csak az ezekhez a gyűjteményekhez hozzáféréssel rendelkező szervezeti tagok láthatják az elemet." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Csak az ezekhez a gyűjteményekhez hozzáféréssel rendelkező szervezeti tagok láthatják az elemeket." }, "bulkCollectionAssignmentWarning": { "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ lejjebb került, $INDEX$/$LENGTH$ pozícióba", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Elem helyek" } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 1cd7311e6cf..81cb2a3700c 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Masuk atau buat akun baru untuk mengakses brankas Anda." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Buat Akun" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Petunjuk Kata Sandi Utama (opsional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -736,6 +745,10 @@ "newUri": { "message": "URl Baru" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item yang Ditambahkan" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Tanya untuk penambahan login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "\"Notifikasi Penambahan Info Masuk\" secara otomatis akan meminta Anda untuk menyimpan info masuk baru ke brankas Anda saat Anda masuk untuk pertama kalinya." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,17 +1272,36 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Aktifkan Isi-Otomatis Saat Memuat Laman" }, "enableAutoFillOnPageLoadDesc": { "message": "Jika formulir info masuk terdeteksi, secara otomatis melakukan pengisian otomatis ketika memuat laman web." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Konfigurasi autofill standard untuk item login." @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Terhubung", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Domain yang Dikecualikan" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ bukan domain yang valid", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Dilindungi kata sandi" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Salin tautan Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 760eeee0544..84e2afa7d8c 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Accedi o crea un nuovo account per accedere alla tua cassaforte." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Crea account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Suggerimento per la password principale (facoltativo)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Scheda" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Nuovo URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Elemento aggiunto" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Chiedi di aggiungere nuovi login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Chiedi di aggiungere un nuovo elemento se non ce n'è uno nella tua cassaforte." }, "addLoginNotificationDescAlt": { "message": "Chiedi di creare un nuovo elemento se non ce n'è uno nella tua cassaforte. Si applica a tutti gli account sul dispositivo." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Mostra le carte nella sezione Scheda" }, "showCardsCurrentTabDesc": { "message": "Mostra le carte nella sezione Scheda per riempirle automaticamente." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Mostra le identità nella sezione Scheda" }, @@ -1220,8 +1242,17 @@ "message": "Mostra il menu di riempimento automatico nei campi di modulo", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Si applica a tutti gli account sul dispositivo." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Disattiva il password manager del tuo browser per evitare conflitti con Bitwarden." @@ -1241,15 +1272,34 @@ "message": "Quando l'icona di riempimento automatico è selezionata", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Riempi automaticamente al caricamento della pagina" + "message": "Abilita l'auto-completamento al caricamento della pagina" }, "enableAutoFillOnPageLoadDesc": { "message": "Se sono rilevati campi di login, riempili automaticamente quando la pagina si carica." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Siti compromessi potrebbero sfruttare il riempimento automatico al caricamento della pagina." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Ulteriori informazioni" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Booleano" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Collegato", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Una politica dell'organizzazione ti impedisce di importare elementi nella tua cassaforte individuale." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Domini esclusi" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden non chiederà di salvare le credenziali di accesso per questi domini per tutti gli account sul dispositivo. Ricarica la pagina affinché le modifiche abbiano effetto." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ non è un dominio valido", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protetto da password" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copia link del Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Impostazioni di riempimento automatico" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Scorciatoia da tastiera per riempire automaticamente" }, @@ -2970,10 +3048,18 @@ "message": "Sblocca il tuo account per visualizzare i login corrispondenti", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Sblocca account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Riempi le credenziali per", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Aggiungi un nuovo elemento alla cassaforte", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Il menu di riempimento automatico di Bitwarden è disponibile. Premi il tasto freccia giù per selezionare.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Password errata, usa la password che hai inserito alla creazione del file di esportazione." }, - "importDestination": { - "message": "Destinazione dell'importazione" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Ulteriori informazioni sulle tue opzioni di importazione" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Formati comuni", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Rendere Bitwarden il tuo password manager predefinito?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assegna raccolte" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copia email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index 9e5654f62c1..da162d03bfc 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "安全なデータ保管庫へアクセスするためにログインまたはアカウントを作成してください。" }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "アカウントの作成" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "マスターパスワードのヒント (省略可能)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "タブ" }, @@ -640,13 +649,13 @@ "message": "現在のウェブページから認証 QR コードをスキャンする" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "2段階認証をシームレスにする" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden は2段階認証コードを保存・入力できます。この欄にキーをコピーして貼り付けてください。" }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden は2段階認証コードを保存・入力できます。 カメラアイコンを選択して、このウェブサイトの認証 QR コードのスクリーンショットを撮るか、キーをコピーしてこのフィールドに貼り付けてください。" }, "copyTOTP": { "message": "認証キーのコピー (TOTP)" @@ -661,19 +670,19 @@ "message": "ログインセッションの有効期限が切れています。" }, "logIn": { - "message": "Log in" + "message": "ログイン" }, "restartRegistration": { - "message": "Restart registration" + "message": "登録を再度始める" }, "expiredLink": { - "message": "Expired link" + "message": "期限切れのリンク" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "登録を再度始めるか、ログインしてください。" }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "すでにアカウントを持っている可能性があります" }, "logOutConfirmation": { "message": "ログアウトしてもよろしいですか?" @@ -736,6 +745,10 @@ "newUri": { "message": "新しい URI" }, + "addDomain": { + "message": "ドメインの追加", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "追加されたアイテム" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "ログイン情報の追加を尋ねる" }, + "vaultSaveOptionsTitle": { + "message": "保管庫のオプションに保存" + }, "addLoginNotificationDesc": { "message": "初めてログインしたとき保管庫にログイン情報を保存するよう「ログイン情報を追加」通知を自動的に表示します。" }, "addLoginNotificationDescAlt": { "message": "保管庫にアイテムが見つからない場合は、アイテムを追加するよう要求します。ログインしているすべてのアカウントに適用されます。" }, + "showCardsInVaultView": { + "message": "保管庫ビューに自動入力の候補としてカードを表示する" + }, "showCardsCurrentTab": { "message": "タブページにカードを表示" }, "showCardsCurrentTabDesc": { "message": "自動入力を簡単にするために、タブページにカードアイテムを表示します" }, + "showIdentitiesInVaultView": { + "message": "保管庫ビューに自動入力の候補として ID を表示する" + }, "showIdentitiesCurrentTab": { "message": "タブページに ID を表示" }, @@ -1220,7 +1242,16 @@ "message": "フォーム項目に自動入力メニューを表示", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "自動入力の候補" + }, + "showInlineMenuLabel": { + "message": "フォームフィールドに自動入力の候補を表示する" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "アイコンが選択されているときに候補を表示する" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "ログインしているすべてのアカウントに適用されます。" }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "自動入力アイコンを選択しているとき", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "ページ読み込み時に自動入力する" + }, "enableAutoFillOnPageLoad": { "message": "ページ読み込み時の自動入力を有効化" }, "enableAutoFillOnPageLoadDesc": { "message": "ページ読み込み時にログインフォームを検出したとき、ログイン情報を自動入力します。" }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$警告:$CLOSETAG$ 侵害された、または信頼できないウェブサイトは、ページ読み込み時の自動入力を悪用する可能性があります。", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "ウイルス感染したり信頼できないウェブサイトは、ページの読み込み時の自動入力を悪用できてしまいます。" }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "リスクについての詳細" + }, "learnMoreAboutAutofill": { "message": "自動入力についての詳細" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "真偽値" }, + "cfTypeCheckbox": { + "message": "チェックボックス" + }, "cfTypeLinked": { "message": "リンク済", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "新しいマスターパスワードは最低要件を満たしていません。" }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Bitwarden からメールでアドバイスやお知らせ、リサーチの機会を受け取りましょう。" }, "unsubscribe": { "message": "配信停止" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "組織のポリシーにより、個々の保管庫へのアイテムのインポートがブロックされました。" }, + "domainsTitle": { + "message": "ドメイン", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "除外するドメイン" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden はログインしているすべてのアカウントで、これらのドメインのログイン情報を保存するよう要求しません。 変更を有効にするにはページを更新する必要があります。" }, + "websiteItemLabel": { + "message": "ウェブサイト $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ は有効なドメインではありません", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "除外ドメインの変更を保存しました" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "パスワード保護あり" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send リンクをコピー", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "自動入力の設定" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "自動入力のショートカット" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "ショートカットの変更" + }, "autofillShortcut": { "message": "自動入力キーボードショートカット" }, @@ -2970,10 +3048,18 @@ "message": "一致するログイン情報を表示するには、アカウントのロックを解除してください", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "アカウントのロックを解除", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "資格情報を入力:", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "新しい保管庫アイテムを追加", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden 自動入力メニューがあります。下矢印キーを押すと選択できます。", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "無効なファイルパスワードです。エクスポートファイルを作成したときに入力したパスワードを使用してください。" }, - "importDestination": { - "message": "インポート先" + "destination": { + "message": "保存先" }, "learnAboutImportOptions": { "message": "インポートオプションの詳細" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "一般的な形式", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "ブラウザの設定に進みますか?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "ヘルプセンターに進みますか?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "ブラウザの自動入力とパスワード管理設定を変更します。", + "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": "拡張機能のショートカットはブラウザの設定で表示および設定できます。", + "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": "ブラウザの自動入力とパスワード管理設定を変更します。", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "拡張機能のショートカットはブラウザの設定で表示および設定できます。", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Bitwarden をデフォルトのパスワードマネージャーにしますか?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "コピーする値がありません" }, - "assignCollections": { - "message": "コレクションを割り当て" + "assignToCollections": { + "message": "コレクションに割り当て" }, "copyEmail": { "message": "メールアドレスをコピー" @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "ログイン情報" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "認証キー" }, "cardDetails": { "message": "カード情報" @@ -3667,14 +3805,20 @@ "loading": { "message": "読み込み中" }, - "assign": { - "message": "Assign" + "data": { + "message": "データ" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "assign": { + "message": "割り当て" + }, + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "これらのコレクションにアクセスできる組織メンバーのみがアイテムを見ることができます。" + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "これらのコレクションにアクセスできる組織メンバーのみがアイテムを見ることができます。" }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "$TOTAL_COUNT$ アイテムを選択しました。編集権限がないため、$READONLY_COUNT$ アイテムを更新できません。", "placeholders": { "total_count": { "content": "$1", @@ -3769,23 +3913,35 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "割り当てるコレクションを選択" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1個のアイテムは選択した組織に恒久的に移行されます。このアイテムはあなたの所有ではなくなります。" + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 個のアイテムは選択した組織に恒久的に移行されます。これらのアイテムはあなたの所有ではなくなります。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1個のアイテムは $ORG$ に恒久的に移行されます。このアイテムはあなたの所有ではなくなります。", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 個のアイテムは $ORG$ に恒久的に移行されます。これらのアイテムはあなたの所有ではなくなります。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3794,13 +3950,31 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "コレクションの割り当てに成功しました" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "何も選択されていません。" }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "選択したアイテムを $ORGNAME$ に移動しました", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemsMovedToOrg": { + "message": "アイテムを $ORGNAME$ に移動しました", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "アイテムを $ORGNAME$ に移動しました", "placeholders": { "orgname": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "アイテムの場所" } } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 2bda6bee217..9ba757cd6af 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "ანგარიშის შექმნა" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index f87a68a30dc..ceecfe3cde3 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Copy security code" }, "autoFill": { - "message": "Auto-fill" + "message": "Autofill" }, "autoFillLogin": { "message": "Auto-fill login" @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index da429e197eb..1550ca5b26e 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "ನಿಮ್ಮ ಸುರಕ್ಷಿತ ವಾಲ್ಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಲಾಗ್ ಇನ್ ಮಾಡಿ ಅಥವಾ ಹೊಸ ಖಾತೆಯನ್ನು ರಚಿಸಿ." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "ಖಾತೆ ತೆರೆ" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "ಮಾಸ್ಟರ್ ಪಾಸ್ವರ್ಡ್ ಸುಳಿವು (ಐಚ್ಛಿಕ)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "ಟ್ಯಾಬ್" }, @@ -736,6 +745,10 @@ "newUri": { "message": "ಹೊಸ ಯುಆರ್ಐ" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "\"ಲಾಗಿನ್ ಅಧಿಸೂಚನೆಯನ್ನು ಸೇರಿಸಿ\" ನೀವು ಮೊದಲ ಬಾರಿಗೆ ಪ್ರವೇಶಿಸಿದಾಗಲೆಲ್ಲಾ ಹೊಸ ಲಾಗಿನ್‌ಗಳನ್ನು ನಿಮ್ಮ ವಾಲ್ಟ್‌ಗೆ ಉಳಿಸಲು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕೇಳುತ್ತದೆ." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,17 +1272,36 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "ಪುಟ ಲೋಡ್‌ನಲ್ಲಿ ಸ್ವಯಂ ಭರ್ತಿ ಸಕ್ರಿಯಗೊಳಿಸಿ" }, "enableAutoFillOnPageLoadDesc": { "message": "ಲಾಗಿನ್ ಫಾರ್ಮ್ ಪತ್ತೆಯಾದಲ್ಲಿ, ವೆಬ್ ಪುಟ ಲೋಡ್ ಆಗುವಾಗ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸ್ವಯಂ ಭರ್ತಿ ಮಾಡಿ." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "ಲಾಗಿನ್ ಐಟಂಗಳಿಗಾಗಿ ಡೀಫಾಲ್ಟ್ ಆಟೋಫಿಲ್ ಸೆಟ್ಟಿಂಗ್" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "ಬೂಲಿಯನ್" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "ಹೊರತುಪಡಿಸಿದ ಡೊಮೇನ್ಗಳು" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ ಮಾನ್ಯವಾದ ಡೊಮೇನ್ ಅಲ್ಲ", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "ಕಳುಹಿಸಿ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "ಪಾಸ್ವರ್ಡ್ ರಕ್ಷಿತ" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "ಲಿಂಕ್ ಕಳುಹಿಸಿ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index e9112a69672..b5edfce2b2d 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "안전 보관함에 접근하려면 로그인하거나 새 계정을 만드세요." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "계정 만들기" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "마스터 비밀번호 힌트 (선택)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "탭" }, @@ -736,6 +745,10 @@ "newUri": { "message": "새 URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "항목 추가함" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "로그인을 추가할 건지 물어보기" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "\"로그인 추가 알림\"을 사용하면 새 로그인을 사용할 때마다 보관함에 그 로그인을 추가할 것인지 물어봅니다." }, "addLoginNotificationDescAlt": { "message": "보관함에 항목이 없을 경우 추가하라는 메시지를 표시합니다. 모든 로그인된 계정에 적용됩니다." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "탭 페이지에 카드 표시" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,8 +1242,17 @@ "message": "입력 필드에 자동 완성 메뉴 표시", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "모든 로그인된 계정에 적용됩니다." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "충돌을 방지하기 위해 브라우저의 기본 암호 관리 설정을 해제합니다." @@ -1241,17 +1272,36 @@ "message": "자동 완성 아이콘이 선택되었을 때", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "페이지 로드 시 자동 완성 사용" }, "enableAutoFillOnPageLoadDesc": { "message": "로그인 양식을 감지하면 웹 페이지 로드 시 자동 완성을 자동으로 수행합니다." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "취약하거나 신뢰할 수 없는 웹사이트 페이지 로드 시 자동 완성이 악용될 수 있습니다." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "로그인 항목에 대한 기본 자동 완성 설정" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "참 / 거짓" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "연결됨", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "제외된 도메인" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ 도메인은 유효한 도메인이 아닙니다.", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "비밀번호로 보호됨" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send 링크 복사", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "자동 완성 설정" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "자동 완성 키보드 단축키" }, @@ -2687,7 +2765,7 @@ "message": "자동 완성 단축키가 설정되지 않았습니다. 브라우저 설정에서 단축키를 변경하세요." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "계정 잠금 해제", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Bitwarden을 기본 비밀번호 관리자로 지정하시겠습니까?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 1f17f6f888c..e80258ccab8 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Prisijunkite arba sukurkite naują paskyrą, kad galėtumėte pasiekti saugyklą." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Sukurti paskyrą" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Pagrindinio slaptažodžio užuomina (neprivaloma)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Skirtukas" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Naujas URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Pridėtas elementas" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Prašyti pridėti prisijungimą" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Prisijungimo pridėjimo pranešimas automatiškai Jūs paragina išsaugoti naujus prisijungimus Jūsų saugykloje, kuomet prisijungiate pirmą kartą." }, "addLoginNotificationDescAlt": { "message": "Paprašykite pridėti elementą, jei jo nerasta Jūsų saugykloje. Taikoma visoms prisijungusioms paskyroms." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Rodyti korteles skirtuko puslapyje" }, "showCardsCurrentTabDesc": { "message": "Pateikti kortelių elementų skirtuko puslapyje sąrašą, kad būtų lengva automatiškai užpildyti." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Rodyti tapatybes skirtuko puslapyje" }, @@ -1220,8 +1242,17 @@ "message": "Rodyti automatinio pildymo meniu formos laukeliuose", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Taikoma visoms prisijungusioms paskyroms." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Išjunkite naršyklėje integruotus slaptažodžių tvarkyklės nustatymus, kad išvengtumėte konfliktų." @@ -1241,15 +1272,34 @@ "message": "Kai pasirinkta automatinio užpildymo piktograma", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Automatiškai užpildyti užsikrovus puslapiui" }, "enableAutoFillOnPageLoadDesc": { "message": "Jei aptikta prisijungimo forma, automatiškai užpildyti, kai kraunamas tinklalapis." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Pažeistos arba nepatikimos svetainės gali išnaudoti automatinį užpildymą įkeliant puslapį." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Sužinokite daugiau apie automatinį užpildymą" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Taip/Ne" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Susieta", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Organizacijos politika blokavo elementų importavimą į Jūsų individualią saugyklą." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Išskirti domenai" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "„Bitwarden“ neprašys išsaugoti prisijungimo detalių šiems domenams, visose prisijungusiose paskyrose. Turite atnaujinti puslapį, kad pokyčiai pradėtų galioti." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ yra klaidingas domenas", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Siųsti", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Apsaugota slaptažodžiu" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopijuoti siuntimo nuorodą", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Atrakinkite savo paskyrą, kad pamatytumėte atitinkamus prisijungimus", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Atrakinti paskyrą", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Užpildykite prisijungimo duomenis", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Pridėti naują saugyklos elementą", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Galimas „Bitwarden“ automatinio pildymo meniu. Norėdami pasirinkti, paspauskite rodyklės žemyn klavišą.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Netinkamas failo slaptažodis, prašome naudoti slaptažodį, kurį įvedėte kurdami eksportuojamą failą." }, - "importDestination": { - "message": "Importavimo paskirties vieta" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Sužinoti apie importavimo parinktis" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Padaryti Bitwarden savo numatytuoju slaptažodžių tvarkytuvu?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 25c58195129..10cf754ab15 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Jāpiesakās vai jāizveido jauns konts, lai piekļūtu drošajai glabātavai." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Izveidot kontu" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Galvenās paroles norāde (nav nepieciešama)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Cilne" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Jauns URI" }, + "addDomain": { + "message": "Pievienot domēna vārdu", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Vienums pievienots" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Vaicāt, lai pievienotu pieteikšanās vienumu" }, + "vaultSaveOptionsTitle": { + "message": "Saglabāt glabātavas iespējās" + }, "addLoginNotificationDesc": { "message": "Vaicāt pievienot vienumu, ja tāds nav atrodams glabātavā." }, "addLoginNotificationDescAlt": { "message": "Vaicāt, vai pievienot vienumu, ja glabātavā tāds nav atrodams. Attiecas uz visiem pieslēgtajiem kontiem." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Rādīt kartes cilnes lapā" }, "showCardsCurrentTabDesc": { "message": "Attēlot kartes ciļņu lapā vieglākai aizpildīšanai." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Rādīt identitātes cilnes pārskatā" }, @@ -1220,8 +1242,17 @@ "message": "Rādīt automātiskās aizpildes izvēlni veidlapu laukos", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Attiecas uz visiem pieslēgtajiem kontiem." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Jāizslēdz sava pārlūka iebūvētā paroļu pārvaldnieka iestatījumi, lai izvairītos no nesaderībām." @@ -1241,15 +1272,34 @@ "message": "Kad tiek atlasīta automātiskās aizpildes ikona", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Automātiski aizpildīt lapas ielādes brīdī" }, "enableAutoFillOnPageLoadDesc": { "message": "Ja tiek noteikta pieteikšanās veidne, tā tiks aizpildīta lapas ielādes brīdī." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Pārveidotās vai neuzticamās tīmekļvietnēs automātiskā aizpilde lapas ielādes laikā var tikt ļaunprātīgi izmantota." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Uzzināt vairāk par automātisko aizpildi" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Patiesuma vērtība" }, + "cfTypeCheckbox": { + "message": "Izvēles rūtiņa" + }, "cfTypeLinked": { "message": "Saistīts", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Apvienības nosacījums neļauj ievietot ārējos vienumus savā personīgajā glabātavā." }, + "domainsTitle": { + "message": "Domēna vārdi", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Izņēmuma domēni" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden nevaicās saglabāt pieteikšanās datus šiem domēniem visiem pieslēgtajiem kontiem. Ir jāpārlādē lapa, lai iedarbotos izmaiņas." }, + "websiteItemLabel": { + "message": "Tīmekļvietne $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ nav derīgs domēns", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Saglabātas vērā neņemto domēna vārdu izmaiņas" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Aizsargāts ar paroli" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Ievietot Send saiti starpliktuvē", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Automātiskās aizpildes iestatījumi" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Automātiskās aizpildes īsinājumtaustiņi" }, @@ -2970,10 +3048,18 @@ "message": "Jāatslēdz savs konts, lai apskatītu atbilstošus pieteikšanās vienumus", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Atslēgt kontu", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Aizpildīt pieteikšanās datus", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Pievienot jaunu glabātavas vienumu", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Ir pieejama Bitwarden automātiskās aizpildes izvēlne. Jānospiež poga ar bultu uz leju, lai atlasītu.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Nederīga datnes parole, lūgums izmantot to paroli, kas tika ievadīta izgūšanas datnes izveidošanas brīdī." }, - "importDestination": { - "message": "Ievietošanas galamērķis" + "destination": { + "message": "Galamērķis" }, "learnAboutImportOptions": { "message": "Uzzināt par ievietošanas iespējām" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Izplatīti veidoli", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Padarīt Bitwarden par noklusējuma paroļu pārvaldnieku?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Nav vērtību, ko ievietot starpliktuvē" }, - "assignCollections": { - "message": "Piešķirt krājumus" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Ievietot starpliktuvē e-pasta adresi" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,11 +3805,17 @@ "loading": { "message": "Ielādē" }, + "data": { + "message": "Dati" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Vienumu varēs redzēt tikai apvnienības dalībnieki ar piekļuvi šiem krājumiem." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Vienumus varēs redzēt tikai apvnienības dalībnieki ar piekļuvi šiem krājumiem." }, "bulkCollectionAssignmentWarning": { "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ pārvietots lejup, $INDEX$. no $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Vienuma atrašanās vieta" } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 3d55d60fdc3..6a58cabbebd 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "നിങ്ങളുടെ സുരക്ഷിത വാൾട്ടിലേക്കു പ്രവേശിക്കാൻ ലോഗിൻ ചെയ്യുക അല്ലെങ്കിൽ ഒരു പുതിയ അക്കൗണ്ട് സൃഷ്ടിക്കുക." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "അക്കൗണ്ട് സൃഷ്ടിക്കുക" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "പ്രാഥമിക പാസ്‌വേഡ് സൂചന (ഇഷ്ടാനുസൃതമായ)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "ടാബ് " }, @@ -736,6 +745,10 @@ "newUri": { "message": "പുതിയ URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "ചേർക്കപ്പെട്ട ഇനം" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "നിങ്ങൾ ആദ്യമായി സൈറ്റിൽ പ്രവേശിക്കുമ്പോൾ നിങ്ങളുടെ വാൾട്ടിലേക്കു തനിയെ പ്രവേശനം ഉൾപെടുത്താൻ \"പ്രവേശനം ചേർക്കുക എന്ന അറിയിപ്പ്\" ആവശ്യപ്പെടും." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "പേജ് ലോഡിൽ യാന്ത്രിക-പൂരിപ്പിക്കൽ പ്രവർത്തനക്ഷമമാക്കുക" }, "enableAutoFillOnPageLoadDesc": { "message": "ഒരു ലോഗിൻ ഫോം കണ്ടെത്തിയാൽ, വെബ് പേജ് ലോഡുചെയ്യുമ്പോൾ യാന്ത്രികമായി ഒരു സ്വയം പൂരിപ്പിക്കൽ നടത്തുക." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "വോൾട്ട് പോപ്പ്അപ്പ് തുറക്കുക" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "ബൂളിയൻ" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 79281e132e2..f6171e18bf6 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "तुमच्या सुरक्षित तिजोरीत पोहचण्यासाठी लॉग इन करा किंवा नवीन खाते उघडा." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "खाते तयार करा" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "मुख्य पासवर्डचा संकेत (पर्यायी)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "टॅब" }, @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index f87a68a30dc..ceecfe3cde3 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Copy security code" }, "autoFill": { - "message": "Auto-fill" + "message": "Autofill" }, "autoFillLogin": { "message": "Auto-fill login" @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 3ab1d376216..98680e64033 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Logg på eller opprett en ny konto for å få tilgang til ditt sikre hvelv." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Opprett en konto" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Et hint for hovedpassordet (valgfritt)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Fane" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Ny URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "La til element" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Spør om å legge til innlogging" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "\"Legg til innlogging\"-beskjeden ber deg automatisk om å lagre nye innlogginger til hvelvet ditt hver gang du logger på dem for første gang." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Vis kort på fanesiden" }, "showCardsCurrentTabDesc": { "message": "Vis kortelementer på fanesiden for lett auto-utfylling." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Vis identiteter på fanesiden" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Rediger nettleserinnstillingene." @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Aktiver auto-utfylling ved sideinnlastning" }, "enableAutoFillOnPageLoadDesc": { "message": "Dersom et innloggingskjema blir oppdaget, utfør automatisk en auto-utfylling når nettstedet lastes inn." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Kompromitterte eller upålitelige nettsider kan utnytte auto-utfylling når du laster inn siden." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Lær mer om auto-utfylling" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolsk verdi" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Tilkoblet", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Ekskluderte domener" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ er ikke et gyldig domene", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Passord beskyttet" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopier Send-lenke", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Innstillinger for auto-utfylling" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Auto-utfyll tastatursnarvei" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Lås opp kontoen", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Legg til nytt hvelvobjekt", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Lær mer om importalternativene dine" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Vanlige formater", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index f87a68a30dc..ceecfe3cde3 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Copy security code" }, "autoFill": { - "message": "Auto-fill" + "message": "Autofill" }, "autoFillLogin": { "message": "Auto-fill login" @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 5355ce67e9d..65a7fef129d 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in of maak een nieuw account aan om toegang te krijgen tot je beveiligde kluis." }, + "inviteAccepted": { + "message": "Uitnodiging geaccepteerd" + }, "createAccount": { "message": "Account aanmaken" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Hoofdwachtwoordhint (optioneel)" }, + "joinOrganization": { + "message": "Lid van organisatie worden" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Voltooi je lidmaatschap aan deze organisatie door een hoofdwachtwoord in te stellen." + }, "tab": { "message": "Tab" }, @@ -661,19 +670,19 @@ "message": "Je inlogsessie is verlopen." }, "logIn": { - "message": "Log in" + "message": "Inloggen" }, "restartRegistration": { - "message": "Restart registration" + "message": "Registratie herstarten" }, "expiredLink": { - "message": "Expired link" + "message": "Verlopen link" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Herstart de registratie of probeer in te loggen." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Je hebt al een account" }, "logOutConfirmation": { "message": "Weet je zeker dat je wilt uitloggen?" @@ -736,6 +745,10 @@ "newUri": { "message": "Nieuwe URI" }, + "addDomain": { + "message": "Domein toevoegen", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item is toegevoegd" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Vraag om toevoegen login" }, + "vaultSaveOptionsTitle": { + "message": "Opslaan in kluisopties" + }, "addLoginNotificationDesc": { "message": "\"Melding bij nieuwe login\" vraagt automatisch om nieuwe sites in de kluis op te slaan wanneer je ergens voor de eerste keer inlogt." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Kaarten als Autofill-suggesties in de kluisweergave weergeven" + }, "showCardsCurrentTab": { "message": "Kaarten weergeven op tabpagina" }, "showCardsCurrentTabDesc": { "message": "Kaartenitems weergeven op de tabpagina voor gemakkelijk automatisch invullen." }, + "showIdentitiesInVaultView": { + "message": "Identiteiten als Autofill-suggesties in de kluisweergave weergeven" + }, "showIdentitiesCurrentTab": { "message": "Identiteiten weergeven op tabpagina" }, @@ -1220,8 +1242,17 @@ "message": "Auto-invulmenu op formuliervelden weergeven", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "autofillSuggestionsSectionTitle": { + "message": "Suggesties voor automatisch invullen" + }, + "showInlineMenuLabel": { + "message": "Suggesties voor automatisch invullen op formuliervelden weergeven" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Suggesties weergeven wanneer pictogram is geselecteerd" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Van toepassing op alle ingelogde accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Schakel de ingebouwde wachtwoordbeheerinstellingen van je browser uit om conflicten te voorkomen." @@ -1241,15 +1272,34 @@ "message": "Wanneer het pictogram automatisch aanvullen is geselecteerd", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Automatisch invullen bij laden van pagina" + }, "enableAutoFillOnPageLoad": { "message": "Automatisch invullen bij laden van pagina" }, "enableAutoFillOnPageLoadDesc": { "message": "Als een inlogformulier wordt gedetecteerd, dan worden de inloggegevens automatisch ingevuld." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Waarschuwing:$CLOSETAG$ Geconpromitteerde of niet-vertrouwde websites kunnen het automatische invullen bij het laden van de pagina misbruiken.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Gehackte of onbetrouwbare websites kunnen auto-invullen tijdens het laden van de pagina misbruiken." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Meer over risico's lezen" + }, "learnMoreAboutAutofill": { "message": "Lees meer over automatisch invullen" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Selectievakje" + }, "cfTypeLinked": { "message": "Gekoppeld", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Je nieuwe hoofdwachtwoord voldoet niet aan de beleidseisen." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Krijg advies, aankondigingen en onderzoeksmogelijkheden van Bitwarden in je inbox." }, "unsubscribe": { "message": "Afmelden" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Organisatiebeleid heeft het importeren van items in je persoonlijke kluis geblokkeerd." }, + "domainsTitle": { + "message": "Domeinen", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Uitgesloten domeinen" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is geen geldig domein", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Uitgesloten domeinwijzigingen opgeslagen" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Beveiligd met wachtwoord" }, + "copyLink": { + "message": "Link kopiëren" + }, "copySendLink": { "message": "Send-link kopiëren", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Instellingen automatisch invullen" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Shortcut voor automatisch invullen" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Snelkoppeling wijzigen" + }, "autofillShortcut": { "message": "Snelkoppeling automatisch invullen" }, @@ -2970,10 +3048,18 @@ "message": "Ontgrendel je account om overeenkomende logins te bekijken", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Je account ontgrendelen om suggesties voor automatisch inloggen te bekijken", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Account ontgrendelen", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Je account ontgrendelen, opent in een nieuw venster", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Inloggegevens invullen voor", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Nieuwe kluisitem toevoegen", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Nieuwe login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Nieuw inlogitem aan kluis toevoegen, openen in een nieuw venster", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Nieuwe kaart", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Nieuw item aan kluis toevoegen, openen in een nieuw venster", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "Nieuwe identiteit", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Nieuw identiteitsitem aan kluis toevoegen, openen in een nieuw venster", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-invulmenu beschikbaar. Druk op de pijltjestoets omlaag om te selecteren.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Onjuist bestandswachtwoord, gebruik het wachtwoord dat je hebt ingevoerd bij het aanmaken van het exportbestand." }, - "importDestination": { - "message": "Importbestemming" + "destination": { + "message": "Bestemming" }, "learnAboutImportOptions": { "message": "Leer meer over je importopties" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Veelvoorkomende formaten", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Doorgaan naar browserinstellingen?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Doorgaan naar Helpcentrum?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "De instellingen voor het beheer van je browser's automatisch invullen en wachtwoorden veranderen.", + "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": "Je kunt sneltoetsen van de extensie bekijken en instellen in de instellingen van je browser.", + "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": "De instellingen voor het beheer van je browser's automatisch invullen en wachtwoorden veranderen.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Je kunt sneltoetsen van de extensie bekijken en instellen in de instellingen van je browser.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Bitwarden als je standaardwachtbeheerder gebruiken?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Geen waarden om te kopiëren" }, - "assignCollections": { - "message": "Collecties toewijzen" + "assignToCollections": { + "message": "Aan collecties toewijzen" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "kaartnummer eindigt met", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Inloggegevens" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Laden" }, + "data": { + "message": "Gegevens" + }, "assign": { "message": "Toewijzen" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Alleen organisatieleden met toegang tot deze collecties kunnen de items zien." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Alleen organisatieleden met toegang tot deze collecties kunnen de items zien." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Collecties voor toewijzen selecteren" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ worden permanent overgedragen aan de geselecteerde organisatie. Je bent niet langer de eigenaar van deze items.", + "personalItemTransferWarningSingular": { + "message": "1 item wordt permanent overgedragen aan de geselecteerde organisatie. Je bent niet langer de eigenaar van dit item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items worden permanent overgedragen aan de geselecteerde organisatie. Je bent niet langer de eigenaar van deze items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ wordt permanent overgedragen aan $ORG$. Je bent niet langer de eigenaar van deze items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item wordt permanent overgedragen aan $ORG$. Je bent niet langer de eigenaar van dit item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items worden permanent overgedragen aan $ORG$. Je bent niet langer de eigenaar van deze items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items verplaatst naar $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Items verplaatst naar $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ is naar boven verplaatst, positie $INDEX$ van $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Itemlocatie" } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index f87a68a30dc..ceecfe3cde3 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Copy security code" }, "autoFill": { - "message": "Auto-fill" + "message": "Autofill" }, "autoFillLogin": { "message": "Auto-fill login" @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index f87a68a30dc..ceecfe3cde3 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Copy security code" }, "autoFill": { - "message": "Auto-fill" + "message": "Autofill" }, "autoFillLogin": { "message": "Auto-fill login" @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 801943de377..e8fe45346a5 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Zaloguj się lub utwórz nowe konto, aby uzyskać dostęp do Twojego bezpiecznego sejfu." }, + "inviteAccepted": { + "message": "Zaproszenie zostało zaakceptowane" + }, "createAccount": { "message": "Utwórz konto" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Podpowiedź do hasła głównego (opcjonalnie)" }, + "joinOrganization": { + "message": "Dołącz do organizacji" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Zakończ dołączanie do tej organizacji przez ustawienie hasła głównego." + }, "tab": { "message": "Karta" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Nowy URI" }, + "addDomain": { + "message": "Dodaj domenę", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Element został dodany" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Poproś o dodanie danych logowania" }, + "vaultSaveOptionsTitle": { + "message": "Zapisz do ustawień sejfu" + }, "addLoginNotificationDesc": { "message": "\"Dodaj powiadomienia logowania\" automatycznie wyświetla monit o zapisanie nowych danych logowania do sejfu przy każdym pierwszym logowaniu." }, "addLoginNotificationDescAlt": { "message": "Poproś o dodanie elementu, jeśli nie zostanie znaleziony w Twoim sejfie. Dotyczy wszystkich zalogowanych kont." }, + "showCardsInVaultView": { + "message": "Pokaż karty jako sugestie autouzupełniania w widoku sejfu" + }, "showCardsCurrentTab": { "message": "Pokaż karty na stronie głównej" }, "showCardsCurrentTabDesc": { "message": "Pokaż elementy karty na stronie głównej, aby ułatwić autouzupełnianie." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Pokaż tożsamości na stronie głównej" }, @@ -1220,7 +1242,16 @@ "message": "Pokaż menu autouzupełniania na polach formularza", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Sugestie autouzupełniania" + }, + "showInlineMenuLabel": { + "message": "Pokaż sugestie autouzupełniania na polach formularza" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Wyświetlaj sugestie kiedy ikona jest zaznaczona" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Dotyczy wszystkich zalogowanych kont." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Gdy wybrano ikonę autouzupełniania", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Włącz autouzupełnianie po załadowaniu strony" + }, "enableAutoFillOnPageLoad": { "message": "Włącz autouzupełnianie po załadowaniu strony" }, "enableAutoFillOnPageLoadDesc": { "message": "Jeśli zostanie wykryty formularz logowania, automatycznie uzupełnij dane logowania po załadowaniu strony." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Ostrzeżenie:$CLOSETAG$ Niebezpieczne witryny są w stanie wykorzystać autouzupełnianie przy wczytywaniu strony.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Zaatakowane lub niezaufane witryny internetowe mogą wykorzystać funkcję autouzupełniania podczas wczytywania strony, aby wyrządzić szkody." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Dowiedz się więcej o ryzyku" + }, "learnMoreAboutAutofill": { "message": "Dowiedz się więcej o autouzupełnianiu" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Wartość logiczna" }, + "cfTypeCheckbox": { + "message": "Pole wyboru" + }, "cfTypeLinked": { "message": "Powiązane pole", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Polityka organizacji zablokowała importowanie elementów do Twojego sejfu." }, + "domainsTitle": { + "message": "Domeny", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Wykluczone domeny" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Aplikacja Bitwarden nie będzie proponować zapisywania danych logowania dla tych domen dla wszystkich zalogowanych kont. Musisz odświeżyć stronę, aby zastosowywać zmiany." }, + "websiteItemLabel": { + "message": "Strona internetowa $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ nie jest prawidłową nazwą domeny", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Zmiany w wykluczonych domenach zapisane" + }, "send": { "message": "Wyślij", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Chroniona hasłem" }, + "copyLink": { + "message": "Kopiuj link" + }, "copySendLink": { "message": "Kopiuj link wysyłki", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Ustawienia autouzupełniania" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Skrót autouzupełniania" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Zmień skrót" + }, "autofillShortcut": { "message": "Skrót klawiaturowy autouzupełniania" }, @@ -2970,10 +3048,18 @@ "message": "Odblokuj swoje konto, aby wyświetlić pasujące elementy", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Odblokuj swoje konto, aby zobaczyć sugestie autouzupełniania", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Odblokuj konto", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Odblokuj swoje konto, otwiera się w nowym oknie", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Wypełnij dane logowania dla", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Dodaj nowy element do sejfu", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Nowe dane logowania", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Dodaj nowe dane logowania do sejfu, otwiera się w nowym oknie", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Nowa karta", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Dodaj nową kartę do sejfu, otwiera się w nowym oknie", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "Nowa tożsamość", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Dodaj nową tożsamość do sejfu, otwiera się w nowym oknie", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Dostępne menu autouzupełniania Bitwarden. Naciśnij przycisk strzałki w dół, aby wybrać.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Hasło do pliku jest nieprawidłowe. Użyj hasła które podano przy tworzeniu pliku eksportu." }, - "importDestination": { - "message": "Miejsce docelowe importu" + "destination": { + "message": "Miejsce docelowe" }, "learnAboutImportOptions": { "message": "Dowiedz się więcej o opcjach importu" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Popularne formaty", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Kontynuować do ustawień przeglądarki?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Kontynuować do centrum pomocy?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Zmień ustawienia autouzupełniania przeglądarki i zarządzania hasłami.", + "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": "Możesz przeglądać i ustawiać skróty klawiaturowe rozszerzeń w ustawieniach przeglądarki.", + "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": "Zmień ustawienia autouzupełniania przeglądarki i zarządzania hasłami.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Możesz przeglądać i ustawiać skróty klawiaturowe rozszerzeń w ustawieniach przeglądarki.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Czy Bitwarden ma być domyślnym menadżerem haseł?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Brak wartości do skopiowania" }, - "assignCollections": { - "message": "Przypisz kolekcje" + "assignToCollections": { + "message": "Przypisz do kolekcji" }, "copyEmail": { "message": "Skopiuj e-mail" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "numer karty kończy się", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Dane logowania" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Wczytywanie" }, + "data": { + "message": "Dane" + }, "assign": { "message": "Przypisz" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Tylko członkowie organizacji z dostępem do tych kolekcji będą mogli zobaczyć ten element." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Tylko członkowie organizacji z dostępem do tych kolekcji będą mogli zobaczyć te elementy." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Wybierz kolekcje do przypisania" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ zostanie trwale przeniesiony do wybranej organizacji. Nie będziesz już posiadać tych elementów.", + "personalItemTransferWarningSingular": { + "message": "1 element zostanie trwale przeniesiony do wybranej organizacji. Nie będziesz już posiadać tego elementu." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ elementów zostanie trwale przeniesionych do wybranej organizacji. Nie będziesz już posiadać tych elementów.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ zostanie trwale przeniesiony do $ORG$. Nie będziesz już właścicielem tych elementów.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 przedmiot zostanie trwale przeniesiony do $ORG$. Nie będziesz już posiadać tego przedmiotu.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ elementy zostaną trwale przeniesione do $ORG$. Nie będziesz już posiadać tych elementów.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Elementy przeniesione do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Element przeniesiony do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ przeniósł się w dół, pozycja $INDEX$ z $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Lokalizacja elementu" } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 4372e973ab8..fde0c398d9e 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Inicie a sessão ou crie uma nova conta para acessar seu cofre seguro." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Criar Conta" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Dica de Senha Mestra (opcional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Aba" }, @@ -612,7 +621,7 @@ "message": "O código de verificação é necessário." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "A autenticação foi cancelada ou demorou muito. Por favor tente novamente." }, "invalidVerificationCode": { "message": "Código de verificação inválido" @@ -640,13 +649,13 @@ "message": "Escaneie o código QR do autenticador na página atual" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Tornar a verificação em duas etapas fácil" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "O Bitwarden pode armazenar e preencher códigos de verificação de duas etapas. Copie e cole a chave neste campo." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "O Bitwarden pode armazenar e preencher códigos de verificação de duas etapas. Selecione o ícone de câmera para tirar uma captura da tela do código QR de autenticador deste site, ou copie e cole a chave neste campo." }, "copyTOTP": { "message": "Copiar chave de Autenticação (TOTP)" @@ -661,19 +670,19 @@ "message": "A sua sessão expirou." }, "logIn": { - "message": "Log in" + "message": "Fazer login" }, "restartRegistration": { - "message": "Restart registration" + "message": "Reiniciar registro" }, "expiredLink": { - "message": "Expired link" + "message": "Link expirado" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Por favor, reinicie o registro ou tente fazer login." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Você pode já ter uma conta" }, "logOutConfirmation": { "message": "Você tem certeza que deseja sair?" @@ -736,6 +745,10 @@ "newUri": { "message": "Novo URI" }, + "addDomain": { + "message": "Adicionar domínio", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item adicionado" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Peça para adicionar login" }, + "vaultSaveOptionsTitle": { + "message": "Salvar nas opções do cofre" + }, "addLoginNotificationDesc": { "message": "A \"Notificação de Adicionar Login\" pede para salvar automaticamente novas logins para o seu cofre quando você inicia uma sessão em um site pela primeira vez." }, "addLoginNotificationDescAlt": { "message": "Pedir para adicionar um item se um não for encontrado no seu cofre. Aplica-se a todas as contas logadas." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Mostrar cartões em páginas com guias." }, "showCardsCurrentTabDesc": { "message": "Exibir itens de cartão em páginas com abas para simplificar o preenchimento automático" }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Exibir Identidades na Aba Atual" }, @@ -1220,8 +1242,17 @@ "message": "Exibir o menu de preenchimento automático nos campos do formulário", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Aplica-se a todas as contas conectadas." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Desative as configurações do gerenciador de senhas do seu navegador para evitar conflitos." @@ -1241,15 +1272,34 @@ "message": "Quando o ícone de preenchimento automático for selecionado", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Ativar o Autopreenchimento ao Carregar a Página" }, "enableAutoFillOnPageLoadDesc": { "message": "Se um formulário de login for detectado, realizar automaticamente um auto-preenchimento quando a página web carregar." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Sites comprometidos ou não confiáveis podem tomar vantagem do autopreenchimento ao carregar a página." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Saiba mais sobre preenchimento automático" }, @@ -1266,10 +1316,10 @@ "message": "Usar configuração padrão" }, "autoFillOnPageLoadYes": { - "message": "Autopreencher ao carregar a página" + "message": "Auto-preencher ao carregar a página" }, "autoFillOnPageLoadNo": { - "message": "Não autopreencher ao carregar a página" + "message": "Não auto-preencher ao carregar a página" }, "commandOpenPopup": { "message": "Abrir pop-up do cofre" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Booleano" }, + "cfTypeCheckbox": { + "message": "Caixa de seleção" + }, "cfTypeLinked": { "message": "Vinculado", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "A sua nova senha mestra não cumpre aos requisitos da política." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Obtenha conselhos, novidades, e oportunidades de pesquisa do Bitwarden em sua caixa de entrada." }, "unsubscribe": { "message": "Cancelar subscrição" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "A política da organização bloqueou a importação de itens para o seu cofre." }, + "domainsTitle": { + "message": "Domínios", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Domínios Excluídos" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "O Bitwarden não irá pedir para salvar os detalhes de credencial para estes domínios. Você deve atualizar a página para que as alterações entrem em vigor." }, + "websiteItemLabel": { + "message": "Site $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ não é um domínio válido", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Mudanças de domínios excluídos salvas" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protegido por senha" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copiar link do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Configurações de autopreenchimento" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Atalho para autopreenchimento" }, @@ -2790,11 +2868,11 @@ "message": "Dispositivo confiável" }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "Nenhum Send ativo", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendsNoItemsMessage": { - "message": "Use Send to securely share encrypted information with anyone.", + "message": "Use o Send para compartilhar informação criptografa com qualquer um.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "inputRequired": { @@ -2970,10 +3048,18 @@ "message": "Desbloqueie sua conta para ver os logins correspondentes", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Desbloquear conta", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Preencha as credenciais para", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Adicionar novo item do cofre", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Menu de autopreenchimento do Bitwarden disponível. Pressione a tecla de seta para baixo para selecionar.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3081,7 +3191,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Erro ao se conectar com o serviço Duo. Use um método de verificação de duas etapas diferente ou contate o Duo para assistência." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Inicie o Duo e siga os passos para finalizar o login." @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Senha do arquivo inválida, por favor informe a senha utilizada quando criou o arquivo de exportação." }, - "importDestination": { - "message": "Destino da Importação" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Saiba mais sobre suas opções de importação" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Formatos comuns", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Tornar o Bitwarden seu gerenciador de senhas padrão?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Não há valores para copiar" }, - "assignCollections": { - "message": "Aplicar coleção" + "assignToCollections": { + "message": "Atribuir à coleções" }, "copyEmail": { "message": "Copiar e-mail" @@ -3547,7 +3681,7 @@ "message": "Nome do item" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "Você não pode remover coleções com permissões de Somente leitura: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -3559,7 +3693,7 @@ "message": "A organização está desativada" }, "owner": { - "message": "Owner" + "message": "Proprietário" }, "selfOwnershipLabel": { "message": "Você", @@ -3578,25 +3712,25 @@ "message": "Última edição" }, "ownerYou": { - "message": "Owner: You" + "message": "Proprietário: Você" }, "linked": { - "message": "Linked" + "message": "Vinculado" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Copiado com Sucesso" }, "upload": { "message": "Fazer upload" }, "addAttachment": { - "message": "Add attachment" + "message": "Adicionar anexo" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "O tamanho máximo de arquivo é de 500 MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "Excluir anexo $NAME$", "placeholders": { "name": { "content": "$1", @@ -3605,7 +3739,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "Baixar $NAME$", "placeholders": { "name": { "content": "$1", @@ -3614,7 +3748,7 @@ } }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "Tem certeza de que deseja excluir este anexo permanentemente?" }, "premium": { "message": "Premium" @@ -3626,16 +3760,16 @@ "message": "Filtros" }, "personalDetails": { - "message": "Personal details" + "message": "Detalhes pessoais" }, "identification": { - "message": "Identification" + "message": "Identificação" }, "contactInfo": { - "message": "Contact info" + "message": "Informação de contato" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "Baixar - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -3643,17 +3777,21 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "Credenciais de login" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Chave do autenticador" }, "cardDetails": { - "message": "Card details" + "message": "Detalhes do cartão" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "Detalhes $BRAND$", "placeholders": { "brand": { "content": "$1", @@ -3662,19 +3800,25 @@ } }, "addAccount": { - "message": "Add account" + "message": "Adicionar conta" }, "loading": { - "message": "Loading" + "message": "Carregando" + }, + "data": { + "message": "Data" }, "assign": { - "message": "Assign" + "message": "Atribuir" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Você selecionou $TOTAL_COUNT$ itens. Você não pode atualizar $READONLY_COUNT$ destes itens porque você não tem permissão de edição.", "placeholders": { "total_count": { "content": "$1", @@ -3686,28 +3830,28 @@ } }, "addField": { - "message": "Add field" + "message": "Adicionar campo" }, "add": { - "message": "Add" + "message": "Adicionar" }, "fieldType": { - "message": "Field type" + "message": "Tipo do campo" }, "fieldLabel": { - "message": "Field label" + "message": "Rótulo do campo" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Utilize campos de texto para dados como questões de segurança" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Use campos ocultos para dados confidenciais como uma senha" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to auto-fill a form's checkbox, like a remember email" + "message": "Use caixas de seleção se gostaria de preencher automaticamente a caixa de seleção de um formulário, como um e-mail de lembrança" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing auto-fill issues for a specific website." + "message": "Use um campo vinculado quando estiver enfrentando problemas com o auto-preenchimento com um site específico." }, "linkedLabelHelpText": { "message": "Enter the the field's html id, name, aria-label, or placeholder." @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Localização do Item" } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 2ba56d3a922..978feaff228 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Inicie sessão ou crie uma nova conta para aceder ao seu cofre seguro." }, + "inviteAccepted": { + "message": "Convite aceite" + }, "createAccount": { "message": "Criar conta" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Dica da palavra-passe mestra (opcional)" }, + "joinOrganization": { + "message": "Aderir à organização" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Conclua a adesão a esta organização ao definir uma palavra-passe mestra." + }, "tab": { "message": "Separador" }, @@ -661,19 +670,19 @@ "message": "A sua sessão expirou." }, "logIn": { - "message": "Log in" + "message": "Iniciar sessão" }, "restartRegistration": { - "message": "Restart registration" + "message": "Reiniciar registo" }, "expiredLink": { - "message": "Expired link" + "message": "Link expirado" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Por favor, reinicie o registo ou tente iniciar sessão." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "É possível que já tenha uma conta" }, "logOutConfirmation": { "message": "Tem a certeza de que pretende terminar sessão?" @@ -736,6 +745,10 @@ "newUri": { "message": "Novo URI" }, + "addDomain": { + "message": "Adicionar domínio", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item adicionado" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Pedir para adicionar credencial" }, + "vaultSaveOptionsTitle": { + "message": "Guardar nas opções do cofre" + }, "addLoginNotificationDesc": { "message": "Pedir para adicionar um item se não o encontrar no seu cofre." }, "addLoginNotificationDescAlt": { "message": "Pedir para adicionar um item se não for encontrado um no seu cofre. Aplica-se a todas as contas com sessão iniciada." }, + "showCardsInVaultView": { + "message": "Mostrar cartões como sugestões de preenchimento automático na vista do cofre" + }, "showCardsCurrentTab": { "message": "Mostrar cartões na página Separador" }, "showCardsCurrentTabDesc": { "message": "Listar itens de cartões na página Separador para facilitar o preenchimento automático." }, + "showIdentitiesInVaultView": { + "message": "Mostrar identidades como sugestões de preenchimento automático na vista do cofre" + }, "showIdentitiesCurrentTab": { "message": "Mostrar identidades na página Separador" }, @@ -858,7 +880,7 @@ "message": "Tema" }, "themeDesc": { - "message": "Alterar o tema de cores da aplicação." + "message": "Altere o tema de cores da aplicação." }, "themeDescAlt": { "message": "Altere o tema de cores da aplicação. Aplica-se a todas as contas com sessão iniciada." @@ -1220,7 +1242,16 @@ "message": "Mostrar menu de preenchimento automático nos campos do formulário", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Sugestões de preenchimento automático" + }, + "showInlineMenuLabel": { + "message": "Mostrar sugestões de preenchimento automático nos campos do formulário" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Apresentar sugestões quando o ícone é selecionado" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Aplica-se a todas as contas com sessão iniciada." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Quando o ícone de preenchimento automático está selecionado", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Preencher automaticamente ao carregar a página" + }, "enableAutoFillOnPageLoad": { "message": "Preencher automaticamente ao carregar a página" }, "enableAutoFillOnPageLoadDesc": { "message": "Se for detetado um formulário de início de sessão, o preenchimento automático é efetuado quando a página Web é carregada." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Aviso:$CLOSETAG$ Aviso: Os sites comprometidos ou não confiáveis podem explorar o preenchimento automático ao carregar a página.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Os sites comprometidos ou não confiáveis podem explorar o preenchimento automático ao carregar a página." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Saber mais sobre os riscos" + }, "learnMoreAboutAutofill": { "message": "Saber mais sobre o preenchimento automático" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Booleano" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Associado", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Uma política da organização bloqueou a importação de itens para o seu cofre individual." }, + "domainsTitle": { + "message": "Domínios", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Domínios excluídos" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "O Bitwarden não pedirá para guardar os detalhes de início de sessão destes domínios para todas as contas com sessão iniciada. É necessário atualizar a página para que as alterações tenham efeito." }, + "websiteItemLabel": { + "message": "Site $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ não é um domínio válido", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Alterações do domínio excluído guardadas" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protegido por palavra-passe" }, + "copyLink": { + "message": "Copiar link" + }, "copySendLink": { "message": "Copiar link do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Definições de preenchimento automático" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Atalho de preenchimento automático" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Alterar atalho" + }, "autofillShortcut": { "message": "Atalho de teclado de preenchimento automático" }, @@ -2970,10 +3048,18 @@ "message": "Desbloqueie a sua conta para ver as credenciais correspondentes", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Desbloqueie a sua conta para ver sugestões de preenchimento automático", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Desbloquear a conta", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Desbloqueie a sua conta, abre numa nova janela", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Preencher as credenciais para", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Adicionar novo item do cofre", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Nova credencial", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Adicione uma nova credencial ao cofre, abre numa nova janela", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Novo cartão", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Adicione um novo cartão ao cofre, abre numa nova janela", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "Nova identidade", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Adicione uma nova identidade ao cofre, abre numa nova janela", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Menu de preenchimento automático Bitwarden disponível. Prima a tecla de seta para baixo para selecionar.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Palavra-passe de ficheiro inválida, utilize a palavra-passe que introduziu quando criou o ficheiro de exportação." }, - "importDestination": { - "message": "Destino da importação" + "destination": { + "message": "Destino" }, "learnAboutImportOptions": { "message": "Saiba mais sobre as suas opções de importação" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Formatos comuns", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continuar para as definições do navegador?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continuar para o Centro de ajuda?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Altere as definições de preenchimento automático e de gestão de palavras-passe do seu navegador.", + "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": "Pode ver e definir atalhos de extensão nas definições do seu navegador.", + "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": "Altere as definições de preenchimento automático e de gestão de palavras-passe do seu navegador.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Pode ver e definir atalhos de extensão nas definições do seu navegador.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Tornar o Bitwarden o seu gestor de palavras-passe predefinido?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignorar esta opção pode causar conflitos entre o menu de preenchimento automático do Bitwarden e o do seu navegador.", + "message": "Ignorar esta opção pode causar conflitos entre as sugestões de preenchimento automático do Bitwarden e as do seu navegador.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Não há valores a copiar" }, - "assignCollections": { - "message": "Atribuir coleções" + "assignToCollections": { + "message": "Atribuir às coleções" }, "copyEmail": { "message": "Copiar e-mail" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "o número do cartão termina com", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Credenciais de início de sessão" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "A carregar" }, + "data": { + "message": "Dados" + }, "assign": { "message": "Atribuir" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Apenas os membros da organização com acesso a estas coleções poderão ver o item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Apenas os membros da organização com acesso a estas coleções poderão ver os itens." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Selecione as coleções a atribuir" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ serão permanentemente transferidos para a organização selecionada. Estes itens deixarão de lhe pertencer.", + "personalItemTransferWarningSingular": { + "message": "1 será permanentemente transferido para a organização selecionada. Este item deixará de lhe pertencer." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ itens serão permanentemente transferidos para a organização selecionada. Estes itens deixarão de lhe pertencer.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ serão permanentemente transferidos para $ORG$. Deixará de ser proprietário destes itens.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 será permanentemente transferido para a $ORG$. Este item deixará de lhe pertencer.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ itens serão permanentemente transferidos para $ORG$. Estes itens deixarão de lhe pertencer.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Itens movidos para $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item movido para $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ movido para baixo, posição $INDEX$ de $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Localização do item" } } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index bc4dad01f6c..2abc6a1024a 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Autentificați-vă sau creați un cont nou pentru a accesa seiful dvs. securizat." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Creare cont" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Indiciu pentru parola principală (opțional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Filă" }, @@ -736,6 +745,10 @@ "newUri": { "message": "URI nou" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Articol adăugat" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Solicitare de adăugare cont" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Solicitați adăugarea unui element dacă nu se găsește unul în seif." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Afișați cardurile pe pagina Filă" }, "showCardsCurrentTabDesc": { "message": "Listați elementele cardului pe pagina Filă pentru a facilita completarea automată." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Afișați identitățile pe pagina Filă" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Completare automată la încărcarea paginii" }, "enableAutoFillOnPageLoadDesc": { "message": "Dacă se detectează un formular de autentificare, completați-l automat la încărcarea paginii web." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Site-urile web compromise sau nesigure pot profita de auto-completarea la încărcare." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Mai multe informații despre auto-completare" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Valoare logică" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Conectat", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Domenii excluse" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ nu este un domeniu valid", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Protejat cu parolă" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copiere link Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Setări de auto-completare" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Scurtătură de tastatură pentru auto-completare" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 0138c5e0b06..f3609eeed5d 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Войдите или создайте новый аккаунт для доступа к вашему защищенному хранилищу." }, + "inviteAccepted": { + "message": "Приглашение принято" + }, "createAccount": { "message": "Создать аккаунт" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Подсказка к мастер-паролю (необяз.)" }, + "joinOrganization": { + "message": "Присоединиться к организации" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Завершите присоединение к этой организации, установив мастер-пароль." + }, "tab": { "message": "Вкладка" }, @@ -661,19 +670,19 @@ "message": "Истек срок действия вашего сеанса." }, "logIn": { - "message": "Log in" + "message": "Войти" }, "restartRegistration": { - "message": "Restart registration" + "message": "Перезапустить регистрацию" }, "expiredLink": { - "message": "Expired link" + "message": "Истекшая ссылка" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Пожалуйста, перезапустите регистрацию или попробуйте авторизоваться." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Возможно, у вас уже есть аккаунт" }, "logOutConfirmation": { "message": "Вы действительно хотите выйти?" @@ -736,6 +745,10 @@ "newUri": { "message": "Новый URI" }, + "addDomain": { + "message": "Добавить домен", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Элемент добавлен" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Спрашивать при добавлении логина" }, + "vaultSaveOptionsTitle": { + "message": "Параметры сохранения в хранилище" + }, "addLoginNotificationDesc": { "message": "Запросить добавление элемента, если его нет в вашем хранилище." }, "addLoginNotificationDescAlt": { "message": "Запрос на добавление элемента, если он отсутствует в вашем хранилище. Применяется ко всем авторизованным аккаунтам." }, + "showCardsInVaultView": { + "message": "Показывать карты как предложение автозаполнения при просмотре Хранилище" + }, "showCardsCurrentTab": { "message": "Показывать карты на вкладке" }, "showCardsCurrentTabDesc": { "message": "Карты будут отображены на вкладке для удобного автозаполнения." }, + "showIdentitiesInVaultView": { + "message": "Показывать личности как предложение автозаполнения при просмотре Хранилище" + }, "showIdentitiesCurrentTab": { "message": "Показывать Личности на вкладке" }, @@ -1220,7 +1242,16 @@ "message": "Показывать меню автозаполнения в полях формы", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Предложения по автозаполнению" + }, + "showInlineMenuLabel": { + "message": "Показывать предположения автозаполнения в полях формы" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Показывать подсказки при выборе значка" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Применяется ко всем авторизованным аккаунтам." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Если выбран значок автозаполнения", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Автозаполнение при загрузке страницы" + }, "enableAutoFillOnPageLoad": { "message": "Автозаполнение при загрузке страницы" }, "enableAutoFillOnPageLoadDesc": { "message": "Если обнаружена форма входа, автозаполнение выполняется при загрузке веб-страницы." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Предупреждение:$CLOSETAG$ взломанные или недоверенные сайты могут использовать автозаполнение при загрузке страницы.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Взломанные или недоверенные сайты могут внедрить вредоносный код во время автозаполнения при загрузке страницы." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Узнайте больше о рисках" + }, "learnMoreAboutAutofill": { "message": "Узнать больше об автозаполнении" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Логическое" }, + "cfTypeCheckbox": { + "message": "Флажок" + }, "cfTypeLinked": { "message": "Связано", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Ваш новый мастер-пароль не соответствует требованиям политики." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Получайте советы, анонсы и возможности для исследований от Bitwarden на свой email." }, "unsubscribe": { "message": "Отписаться" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Импорт элементов в ваше личное хранилище отключен политикой организации." }, + "domainsTitle": { + "message": "Домены", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Исключенные домены" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden не будет предлагать сохранение логинов для этих доменов для всех авторизованных аккаунтов. Для вступления изменений в силу необходимо обновить страницу." }, + "websiteItemLabel": { + "message": "Сайт $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ – некорректно указанный домен", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Изменения в исключенном домене сохранены" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Защищено паролем" }, + "copyLink": { + "message": "Скопировать ссылку" + }, "copySendLink": { "message": "Скопировать ссылку на Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Настройки автозаполнения" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Ярлык автозаполнения" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Изменить ярлык" + }, "autofillShortcut": { "message": "Сочетание клавиш для автозаполнения" }, @@ -2970,10 +3048,18 @@ "message": "Разблокируйте ваш аккаунт для просмотра подходящих логинов", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Разблокируйте ваш аккаунт для просмотра предложений по автозаполнению", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Разблокировать аккаунт", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Разблокируйте ваш аккаунт, откроется в новом окне", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Заполнить учетные данные", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Добавить новый элемент в хранилище", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Новый логин", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Добавление нового логина в хранилище, откроется в новом окне", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Новая карта", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Добавление новой карты в хранилище, откроется в новом окне", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "Новая личность", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Добавление новой личности в хранилище, откроется в новом окне", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Доступно меню автозаполнения Bitwarden. Для выбора нажмите клавишу со стрелкой вниз.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Неверный пароль к файлу. Используйте пароль, введенный при создании файла экспорта." }, - "importDestination": { - "message": "Цель импорта" + "destination": { + "message": "Назначение" }, "learnAboutImportOptions": { "message": "Узнайте о возможностях импорта" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Основные форматы", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Перейти к настройкам браузера?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Перейти в справочный центр?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Измените настройки автозаполнения и управления паролями в своем браузере.", + "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": "Вы можете просматривать и устанавливать ярлыки расширений в настройках браузера.", + "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": "Измените настройки автозаполнения и управления паролями в своем браузере.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Вы можете просматривать и устанавливать ярлыки расширений в настройках браузера.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Сделать Bitwarden менеджером паролей по умолчанию?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Отключение этого параметра может привести к конфликту между меню автозаполнения Bitwarden и вашим браузером.", + "message": "Игнорирование этого параметра может привести к конфликту между автозаполнениями Bitwarden и вашего браузера.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Нет значений для копирования" }, - "assignCollections": { - "message": "Назначить коллекции" + "assignToCollections": { + "message": "Назначить коллекциям" }, "copyEmail": { "message": "Скопировать email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "номер карты заканчивается на", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Данные для авторизации" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Загрузка" }, + "data": { + "message": "Данные" + }, "assign": { "message": "Назначить" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Только члены организации, имеющие доступ к этим коллекциям, смогут видеть элементы." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Только члены организации, имеющие доступ к этим коллекциям, смогут видеть элементы." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Выбрать коллекции для назначения" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ будут навсегда переданы выбранной организации. Вы больше не будете владельцем этих элементов.", + "personalItemTransferWarningSingular": { + "message": "1 элемент будет навсегда передан выбранной организации. Вы больше не будете владельцем этих элементов." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ элементов будут навсегда переданы выбранной организации. Вы больше не будете владельцем этих элементов.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ будут навсегда переданы $ORG$. Вы больше не будете владельцем этих элементов.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 элемент будет навсегда передан $ORG$. Вы больше не будете владельцем этих элементов.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ элементов будут навсегда переданы $ORG$. Вы больше не будете владельцем этих элементов.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Элементы перемещены в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Элемент перемещен в $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ перемещено вниз, позиция $INDEX$ $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Расположение элемента" } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 994c2891add..ff003cce7de 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "ඔබගේ ආරක්ෂිත සුරක්ෂිතාගාරය වෙත පිවිසීමට හෝ නව ගිණුමක් නිර්මාණය කරන්න." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "ගිණුමක් සාදන්න" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "ප්රධාන මුරපදය ඉඟියක් (විකල්ප)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "ටැබ්" }, @@ -736,6 +745,10 @@ "newUri": { "message": "නව වර්ගය" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "එකතු කරන ලද අයිතමය" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "මෙම “ලොගින් වන්න නිවේදනය එකතු කරන්න” ස්වයංක්රීයව ඔබ පළමු වරට ඔවුන් තුලට ප්රවිෂ්ට සෑම අවස්ථාවකදීම ඔබගේ සුරක්ෂිතාගාරය නව පිවිසුම් බේරා ගැනීමට ඔබෙන් විමසනු." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,17 +1272,36 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "පිටු පැටවුම් මත ස්වයංක්රීය-පිරවීම සක්රීය" }, "enableAutoFillOnPageLoadDesc": { "message": "පිවිසුම් පෝරමයක් අනාවරණය කර ඇත්නම්, වෙබ් පිටුව පැටවුම් කරන විට ස්වයංක්රීයව ස්වයංක්රීයව පිරවීම සිදු කරන්න." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "පිවිසුම් අයිතම සඳහා පෙරනිමි autofill සැකසුම" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "බූලියන්" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "සම්බන්ධිත", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "බැහැර වසම්" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ වලංගු වසමක් නොවේ", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "යවන්න", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "මුරපදය ආරක්ෂා" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "සබැඳිය යවන්න පිටපත් කරන්න", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 127888ca2c6..09c309cafd3 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Prihláste sa, alebo vytvorte nový účet pre prístup k vášmu bezpečnému trezoru." }, + "inviteAccepted": { + "message": "Pozvánka prijatá" + }, "createAccount": { "message": "Vytvoriť účet" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Nápoveda k hlavnému heslu (voliteľné)" }, + "joinOrganization": { + "message": "Pripojte sa k organizácii" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Dokončite pripojenie k tejto organizácii nastavením hlavného hesla." + }, "tab": { "message": "Karta" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Nové URI" }, + "addDomain": { + "message": "Pridať doménu", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Pridaná položka" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Požiadať o pridanie prihlásenia" }, + "vaultSaveOptionsTitle": { + "message": "Uložiť do nastavení trezora" + }, "addLoginNotificationDesc": { "message": "Opýtať sa na pridanie prihlasovacích údajov ak ich ešte nemáte v trezore." }, "addLoginNotificationDescAlt": { "message": "Požiada o pridanie položky, ak sa v trezore nenachádza. Platí pre všetky prihlásené účty." }, + "showCardsInVaultView": { + "message": "Zobraziť karty ako návrhy automatického vypĺňania v zobrazení trezora" + }, "showCardsCurrentTab": { "message": "Zobraziť karty na stránke \"Aktuálna karta\"" }, "showCardsCurrentTabDesc": { "message": "Zoznam položiek karty na stránke \"Aktuálna karta\" na jednoduché automatické vyplnenie." }, + "showIdentitiesInVaultView": { + "message": "Zobraziť identity ako návrhy automatického vypĺňania v zobrazení trezora" + }, "showIdentitiesCurrentTab": { "message": "Zobraziť identity na stránke \"Aktuálna karta\"" }, @@ -1220,7 +1242,16 @@ "message": "Zobraziť ponuku automatického vypĺňania na poliach formulára", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Návrhy automatického vypĺňania" + }, + "showInlineMenuLabel": { + "message": "Zobraziť návrhy automatického vypĺňania v poliach formulára" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Zobraziť návrhy, keď je vybratá ikona" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Platí pre všetky prihlásené účty." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Keď je vybratá ikona automatického vypĺňania", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Povoliť automatické vypĺňanie pri načítaní stránky" + }, "enableAutoFillOnPageLoad": { "message": "Povoliť automatické vypĺňanie pri načítaní stránky" }, "enableAutoFillOnPageLoadDesc": { "message": "Ak je detekovaný prihlasovací formulár, automaticky vykonať vypĺňanie pri načítaní stránky." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Upozornenie:$CLOSETAG$ Kompromitované alebo nedôveryhodné webové stránky môžu využívať automatické vypĺňanie pri načítaní stránky.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Skompromitované alebo nedôveryhodné stránky môžu pri svojom načítaní zneužiť automatické dopĺňanie." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Viac informácií o rizikách" + }, "learnMoreAboutAutofill": { "message": "Dozvedieť sa viac o automatickom dopĺňaní" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Začiarkavacie políčko" + }, "cfTypeLinked": { "message": "Prepojené", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Zásady organizácie zablokovali importovanie položiek do vášho osobného trezoru." }, + "domainsTitle": { + "message": "Domény", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Vylúčené domény" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden nebude požadovať ukladanie prihlasovacích údajov pre tieto domény pre všetky prihlásené účty. Aby sa zmeny prejavili, musíte stránku obnoviť." }, + "websiteItemLabel": { + "message": "Webstránka $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ nie je platná doména", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Uložené zmeny vylúčenej domény" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Chránené heslom" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopírovať odkaz na Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Nastavenia automatického vypĺňania" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Skratka automatického vypĺňania" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Zmeniť skratku" + }, "autofillShortcut": { "message": "Klávesová skratka automatického vypĺňania" }, @@ -2970,10 +3048,18 @@ "message": "Odomknite svoj účet na zobrazenie zodpovedajúcich prihlasovacích údajov", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Odomknite svoj účet na zobrazenie návrhov automatického vypĺňania", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Odomknúť účet", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Vyplňte prihlasovacie údaje pre", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Pridať novú položku trezoru", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Nové prihlasovacie údaje", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Nová karta", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "K dispozícii je ponuka automatického vyplňovania Bitwardenu. Stlačte tlačidlo so šípkou nadol a vyberte.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Neplatné heslo súboru, použite heslo, ktoré ste zadali pri vytváraní exportného súboru." }, - "importDestination": { - "message": "Cieľ importu" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Zistiť viac o možnostiach importu" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Bežné formáty", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Pokračovať do nastavení prehliadača?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Pokračovať v centre pomoci?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Zmeňte nastavenia automatického vypĺňania a správy hesiel vo svojom prehliadači.", + "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": "Skratky rozšírenia môžete zobraziť a nastaviť v nastaveniach prehliadača.", + "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": "Zmeňte nastavenia automatického vypĺňania a správy hesiel vo svojom prehliadači.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Skratky rozšírenia môžete zobraziť a nastaviť v nastaveniach prehliadača.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Nastaviť Bitwarden ako predvoleného správcu hesiel?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Nie je čo kopírovať" }, - "assignCollections": { - "message": "Prideliť zbierky" + "assignToCollections": { + "message": "Prideliť k zbierkam" }, "copyEmail": { "message": "Skopírovať e-mail" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "karta končí číslom", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Prihlasovacie údaje" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Načíta sa" }, + "data": { + "message": "Data" + }, "assign": { "message": "Priradiť" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Položku si budú môcť pozrieť len členovia organizácie s prístupom k týmto zbierkam." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Položky si budú môcť pozrieť len členovia organizácie s prístupom k týmto zbierkam." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Vyberte zbierky na priradenie" }, - "personalItemsTransferWarning": { + "personalItemTransferWarningSingular": { + "message": "Položka sa natrvalo presunie do vybranej organizácie. Už ju nebudete vlastniť." + }, + "personalItemsTransferWarningPlural": { "message": "Do vybranej organizácie sa natrvalo presunú $PERSONAL_ITEMS_COUNT$. Tieto položky už nebudete vlastniť.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "Do $ORG$ sa natrvalo presunú $PERSONAL_ITEMS_COUNT$. Tieto položky už nebudete vlastniť.", + "personalItemWithOrgTransferWarningSingular": { + "message": "Do $ORG$ sa natrvalo presunie jedna položka. Položku už nebudete vlastniť.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "Do $ORG$ sa natrvalo presunú $PERSONAL_ITEMS_COUNT$ položky. Tieto položky už nebudete vlastniť.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Položky presunuté do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Položka presunutá do $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ presunuté nižšie, pozícia $INDEX$/$LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Umiestnenie položky" } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 32adb83689c..b2a3c51ef40 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Prijavite se ali ustvarite nov račun za dostop do svojega varnega trezorja." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Ustvari račun" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Namig za glavno geslo (neobvezno)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Zavihek" }, @@ -736,6 +745,10 @@ "newUri": { "message": "Nov URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Element dodan" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Predlagaj dodajanje prijave" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Predlagaj dodajanje novega elementa, če v trezorju ni ustreznega." }, "addLoginNotificationDescAlt": { "message": "Če predmeta ni v trezorju, ga je potrebno dodati. Velja za vse prijavljene račune." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Prikaži kartice na strani Zavihek" }, "showCardsCurrentTabDesc": { "message": "Na strani Zavihek prikaži kartice za lažje samodejno izpoljnjevanje." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Prikaži identitete na strani Zavihek" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,15 +1272,34 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Samodejno izpolni, ko se stran naloži" }, "enableAutoFillOnPageLoadDesc": { "message": "Če Bitwarden na strani zazna prijavni obrazec, ga samodejno izpolni takoj, ko se stran naloži." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Spletne strani, ki jim ne zaupate ali v katere so vdrli, lahko zlorabijo samodejno izpolnjevanje ob naložitvi strani." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Preberite več o samodejnem izpolnjevanju" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Logična vrednost" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Povezano polje", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Izključene domene" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ ni veljavna domena", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Pošiljke", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopiraj povezavo pošiljke", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Nastavitve" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Bližnjica za samodejno izpolnjevanje" }, @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index b2d11120381..4b737fdc17f 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Пријавите се или креирајте нови налог за приступ сефу." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Креирај налог" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Савет Главне Лозинке (опционо)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Језичак" }, @@ -640,13 +649,13 @@ "message": "Скенирајте QR кôд аутентификатора са тренутне веб странице" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Учините верификацију у 2 корака беспрекорном" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden може да чува и попуњава верификационе кодове у 2 корака. Копирајте и налепите кључ у ово поље." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden може да чува и попуњава верификационе кодове у 2 корака. Изаберите икону камере да бисте направили снимак екрана QR кода за аутентификацију ове веб локације или копирајте и налепите кључ у ово поље." }, "copyTOTP": { "message": "Копирати једнократни кôд (TOTP)" @@ -661,19 +670,19 @@ "message": "Ваша сесија је истекла." }, "logIn": { - "message": "Log in" + "message": "Пријави се" }, "restartRegistration": { - "message": "Restart registration" + "message": "Поново покрените регистрацију" }, "expiredLink": { - "message": "Expired link" + "message": "Истекла веза" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Поново покрените регистрацију или покушајте да се пријавите." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Можда већ имате налог" }, "logOutConfirmation": { "message": "Заиста желите да се одјавите?" @@ -736,6 +745,10 @@ "newUri": { "message": "Нови линк" }, + "addDomain": { + "message": "Додај домен", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Ставка додата" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Питај пре додавања" }, + "vaultSaveOptionsTitle": { + "message": "Опције чувања у сефу" + }, "addLoginNotificationDesc": { "message": "„Нотификације Додај Лозинку“ аутоматски тражи да сачувате нове пријаве у сефу кад год се први пут пријавите на њих." }, "addLoginNotificationDescAlt": { "message": "Затражите да додате ставку ако она није пронађена у вашем сефу. Односи се на све пријављене налоге." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Прикажи кредитне картице на страници картице" }, "showCardsCurrentTabDesc": { "message": "Прикажи ставке кредитних картица на страници картице за лакше аутоматско допуњавање." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Прикажи идентитете на страници" }, @@ -1220,8 +1242,17 @@ "message": "Прикажи мени за ауто-попуњавање на пољима обрасца", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Односи се на све пријављене налоге." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Искључите уграђен менаџер лозинки вашег претраживача да бисте избегли сукобе." @@ -1241,15 +1272,34 @@ "message": "Када је изабрана икона ауто-попуњавања", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Омогући аутоматско попуњавање након учитавања странице" }, "enableAutoFillOnPageLoadDesc": { "message": "Ако се открије образац за пријаву, извршите аутоматско попуњавање када се веб страница учита." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Компромитоване или непоуздане веб локације могу да искористе ауто-пуњење при учитавању странице." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Сазнајте више о ауто-пуњење" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Булове" }, + "cfTypeCheckbox": { + "message": "Поље за потврду" + }, "cfTypeLinked": { "message": "Повезано", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Политика организације је блокирала увоз ставки у ваш појединачни сеф." }, + "domainsTitle": { + "message": "Домени", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Изузети домени" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden неће тражити да сачува податке за пријављивање за ове домене за све пријављене налоге. Морате освежити страницу да би промене ступиле на снагу." }, + "websiteItemLabel": { + "message": "Сајт $number$ (УРЛ)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ није важећи домен", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Изузете промене домена су сачуване" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Заштићено лозинком" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Копирај УРЛ „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Подешавања Ауто-пуњења" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Пречице Ауто-пуњења" }, @@ -2970,10 +3048,18 @@ "message": "Откључајте налог да бисте видели подударне пријаве", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Откључај налог", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Попунити акредитиве за", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Додајте нову ставку сефу", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Мени ауто-попуњавања Bitwarden-а је доступан. Притисните тастер са стрелицом надоле да бисте изабрали.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Неважећа лозинка за датотеку, користите лозинку коју сте унели када сте креирали датотеку за извоз." }, - "importDestination": { - "message": "Смештај увоза" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Сазнајте више о опцијама увоза" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Уобичајени формати", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Урадите да Bitwarden буде ваш подразумевани менаџер лозинки?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Нема вредности за копирање" }, - "assignCollections": { - "message": "Додели колекције" + "assignToCollections": { + "message": "Додели колекцијама" }, "copyEmail": { "message": "Копирај имејл" @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "Акредитиве за пријављивање" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Кључ аутентификатора" }, "cardDetails": { "message": "Детаљи картице" @@ -3667,14 +3805,20 @@ "loading": { "message": "Учитавање" }, - "assign": { - "message": "Assign" + "data": { + "message": "Подаци" }, - "bulkCollectionAssignmentDialogDescription": { + "assign": { + "message": "Додели" + }, + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Одабрали сте $TOTAL_COUNT$ ставки. Не можете да ажурирате $READONLY_COUNT$ од ставки јер немате дозволе за уређивање.", "placeholders": { "total_count": { "content": "$1", @@ -3769,23 +3913,35 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Изаберите колекције за доделу" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 ставка биће трајно пребачена у изабрану организацију. Више нећете имати ову ставку." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 ставка биће трајно пребачена у $ORG$. Више нећете имати ову ставку.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ ставке биће трајно пребачени у $ORG$. Више нећете имати ове ставке.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3794,13 +3950,31 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Успешно додељене колекције" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Нисте ништа изабрали." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Одабране ставке премештене у $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemsMovedToOrg": { + "message": "Ставке премештене у $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Ставка премештена у $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Смештај ставке" } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 8c4693e7008..a353fba48f5 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Logga in eller skapa ett nytt konto för att komma åt ditt säkra valv." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Skapa konto" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Huvudlösenordsledtråd (valfri)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Flik" }, @@ -661,7 +670,7 @@ "message": "Din inloggningssession har upphört." }, "logIn": { - "message": "Log in" + "message": "Logga in" }, "restartRegistration": { "message": "Restart registration" @@ -736,6 +745,10 @@ "newUri": { "message": "Ny URI" }, + "addDomain": { + "message": "Lägg till domän", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Nytt objekt skapat" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Be om att lägga till inloggning" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Be om att lägga till ett objekt om det inte finns i ditt valv." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Visa kort på fliksida" }, "showCardsCurrentTabDesc": { "message": "Lista kortobjekt på fliksidan för enkel automatisk fyllning." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Visa identiteter på fliksidan" }, @@ -1220,11 +1242,20 @@ "message": "Visa menyn för automatisk ifyllnad på formulärfält", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Gäller för alla inloggade konton." + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Redigera webbläsarinställningar." @@ -1241,15 +1272,34 @@ "message": "När ikonen för automatisk ifyllnad är vald", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Aktivera automatisk ifyllnad vid sidhämtning" }, "enableAutoFillOnPageLoadDesc": { "message": "Utför automatisk ifyllnad om ett inloggningsformulär upptäcks när webbsidan laddas." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Komprometterade eller ej betrodda webbplatser kan utnyttja automatisk ifyllnad vid sidladdning." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Läs mer om automatisk ifyllnad" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Kryssruta" + }, "cfTypeLinked": { "message": "Länkat", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domäner", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Exkluderade domäner" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ är inte en giltig domän", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Lösenordsskyddad" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Kopiera Send-länk", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Inställningar för automatisk ifyllnad" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Ändra genväg" + }, "autofillShortcut": { "message": "Tangentbordsgenväg för automatisk ifyllnad" }, @@ -2970,10 +3048,18 @@ "message": "Lås upp ditt konto för att visa matchande inloggningar", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Lås upp konto", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fyll i uppgifter för", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Lägg till nytt valvobjekt", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden automatisk ifyllnadsmeny är tillgänglig. Tryck på nedåtpilen för att välja.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Ogiltigt fillösenord, använd lösenordet du angav när du skapade exportfilen." }, - "importDestination": { - "message": "Importdestination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Läs mer om dina importalternativ" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Vanliga format", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Fortsätt till Hjälpcenter?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Låt Bitwarden hantera lösenord som standard?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Tilldela samlingar" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Autentiseringsnyckel" }, "cardDetails": { "message": "Card details" @@ -3667,11 +3805,17 @@ "loading": { "message": "Laddar" }, + "data": { + "message": "Data" + }, "assign": { "message": "Tilldela" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Endast organisationsmedlemmar med tillgång till dessa samlingar kommer att kunna se objekten." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index f87a68a30dc..ceecfe3cde3 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -108,7 +117,7 @@ "message": "Copy security code" }, "autoFill": { - "message": "Auto-fill" + "message": "Autofill" }, "autoFillLogin": { "message": "Auto-fill login" @@ -736,6 +745,10 @@ "newUri": { "message": "New URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Item added" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Ask to add login" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Show cards on Tab page" }, "showCardsCurrentTabDesc": { "message": "List card items on the Tab page for easy auto-fill." }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Show identities on Tab page" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 061bb877c19..9f5649ba759 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "ล็อกอิน หรือ สร้างบัญชีใหม่ เพื่อใช้งานตู้นิรภัยของคุณ" }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "สร้างบัญชี" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master Password Hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "แท็บ" }, @@ -736,6 +745,10 @@ "newUri": { "message": "เพิ่ม URI ใหม่" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "เพิ่มรายการแล้ว" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "ถามเพื่อให้เพิ่มการเข้าสู่ระบบ" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "The \"Add Login Notification\" automatically prompts you to save new logins to your vault whenever you log into them for the first time." }, "addLoginNotificationDescAlt": { "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "แสดงการ์ดบนหน้าแท็บ" }, "showCardsCurrentTabDesc": { "message": "บัตรรายการในหน้าแท็บเพื่อให้ป้อนอัตโนมัติได้ง่าย" }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "แสดงตัวตนบนหน้าแท็บ" }, @@ -1220,11 +1242,20 @@ "message": "Show auto-fill menu on form fields", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "Turn off your browser's built in password manager settings to avoid conflicts." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." @@ -1241,23 +1272,42 @@ "message": "When auto-fill icon is selected", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "Enable Auto-fill On Page Load." }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, auto-fill when the web page loads." + "message": "If a login form is detected, autofill when the web page loads." + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Compromised or untrusted websites can exploit autofill on page load." + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Learn more about autofill" }, "defaultAutoFillOnPageLoad": { "message": "Default autofill setting for login items" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off auto-fill on page load for individual login items from the item's Edit view." + "message": "You can turn off autofill on page load for individual login items from the item's Edit view." }, "itemAutoFillOnPageLoad": { "message": "Auto-fill on page load (if set up in Options)" @@ -1266,10 +1316,10 @@ "message": "Use default setting" }, "autoFillOnPageLoadYes": { - "message": "Auto-fill on page load" + "message": "Autofill on page load" }, "autoFillOnPageLoadNo": { - "message": "Do not auto-fill on page load" + "message": "Do not autofill on page load" }, "commandOpenPopup": { "message": "Open vault popup" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "Linked", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "An organization policy has blocked importing items into your individual vault." }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ is not a valid domain", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Password protected" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Copy Send link", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,14 +2752,20 @@ "autofillSettings": { "message": "Auto-fill settings" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "Autofill keyboard shortcut" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "The autofill shortcut is not set. Change this in the browser's settings." }, "autofillShortcutText": { - "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", + "message": "The autofill shortcut is: $COMMAND$. Change this in the browser's settings.", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "Unlock your account to view matching logins", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Unlock account", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Fill credentials for", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Add new vault item", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Invalid file password, please use the password you entered when you created the export file." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Learn about your import options" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 4296f2bf007..dfe064b1778 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Güvenli kasanıza ulaşmak için giriş yapın veya yeni bir hesap oluşturun." }, + "inviteAccepted": { + "message": "Davet kabul edildi" + }, "createAccount": { "message": "Hesap oluştur" }, @@ -50,7 +53,7 @@ "message": "Ana parolanızı unutursanız bu ipucuna bakınca size ana parolanızı hatırlatacak bir şey yazabilirsiniz." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Parolanızı unutursanız parola ipucunuzu e-posta adresinize gönderebiliriz. Maksimum $CURRENT$/$MAXIMUM$ karakter.", "placeholders": { "current": { "content": "$1", @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Ana parola ipucu (isteğe bağlı)" }, + "joinOrganization": { + "message": "Kuruluşa katıl" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Kuruluşa katılmayı tamamlamak için ana parolanızı belirleyin." + }, "tab": { "message": "Sekme" }, @@ -612,7 +621,7 @@ "message": "Doğrulama kodu gereklidir." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Kimlik doğrulama iptal edildi ve çok uzun sürdü. Lütfen yeniden deneyin." }, "invalidVerificationCode": { "message": "Geçersiz doğrulama kodu" @@ -661,19 +670,19 @@ "message": "Oturumunuz zaman aşımına uğradı." }, "logIn": { - "message": "Log in" + "message": "Giriş yap" }, "restartRegistration": { - "message": "Restart registration" + "message": "Kaydı yeniden başlat" }, "expiredLink": { - "message": "Expired link" + "message": "Bağlantının süresi dolmuş" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Lütfen kaydı yeniden başlatın veya giriş yapmayı deneyin." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Zaten hesabınız olabilir" }, "logOutConfirmation": { "message": "Çıkış yapmak istediğinize emin misiniz?" @@ -736,6 +745,10 @@ "newUri": { "message": "Yeni URI" }, + "addDomain": { + "message": "Alan adı ekle", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Kayıt eklendi" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Hesap eklemeyi öner" }, + "vaultSaveOptionsTitle": { + "message": "Kasa seçeneklerine kaydet" + }, "addLoginNotificationDesc": { "message": "\"Hesap ekle\" bildirimi, ilk kez kullandığınız hesap bilgilerini kasanıza kaydetmek isteyip istemediğinizi otomatik olarak sorar." }, "addLoginNotificationDescAlt": { "message": "Kasanızda bulunmayan kayıtların eklenmesini isteyip istemediğinizi sorar. Oturum açmış tüm hesaplar için geçerlidir." }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "Sekme sayfasında kartları göster" }, "showCardsCurrentTabDesc": { "message": "Kolay otomatik doldurma için sekme sayfasında kart öğelerini listele" }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "Sekme sayfasında kimlikleri göster" }, @@ -1145,17 +1167,17 @@ "message": "Kimlik doğrulama uygulaması" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Kimlik doğrulama uygulamanızın (örn. Bitwarden Authenticator) ürettiği kodu girin.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "YubiKey OTP güvenlik anahtarı" }, "yubiKeyDesc": { "message": "Hesabınıza erişmek için bir YubiKey kullanın. YubiKey 4, 4 Nano, 4C ve NEO cihazlarıyla çalışır." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Duo Security'nin ürettiği kodu girin.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1172,7 +1194,7 @@ "message": "E-posta" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "E-posta adresinize gönderilen kodu girin." }, "selfHostedEnvironment": { "message": "Şirket içinde barındırılan ortam" @@ -1220,7 +1242,16 @@ "message": "Form alanlarında otomatik doldurma menüsünü göster", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Önerileri otomatik doldur" + }, + "showInlineMenuLabel": { + "message": "Form alanlarında otomatik doldurma önerilerini göster" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Oturum açmış tüm hesaplara uygulanır." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,15 +1272,34 @@ "message": "Otomatik doldurma simgesi seçildiğinde", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Sayfa yüklendiğinde otomatik doldur" + }, "enableAutoFillOnPageLoad": { "message": "Sayfa yüklendiğinde otomatik doldur" }, "enableAutoFillOnPageLoadDesc": { "message": "Sayfa yüklendiğinde giriş formu tespit edilirse otomatik olarak formu doldur." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Ele geçirilmiş veya güvenilmeyen web siteleri sayfa yüklenirken otomatik doldurmayı suistimal edebilir." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "Otomatik doldurma hakkında bilgi alın" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Boolean" }, + "cfTypeCheckbox": { + "message": "Onay kutusu" + }, "cfTypeLinked": { "message": "Bağlantılı", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Bir kuruluş ilkesi, kayıtları kişisel kasanıza içe aktarmayı engelledi." }, + "domainsTitle": { + "message": "Alan adları", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Hariç tutulan alan adları" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden, oturum açmış tüm hesaplar için bu alan adlarının hesap bilgilerini kaydetmeyi sormayacaktır. Değişikliklerin etkili olması için sayfayı yenilemeniz gerekir." }, + "websiteItemLabel": { + "message": "Web sitesi $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ geçerli bir alan adı değil", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Alan adı istisnası değişiklikleri kaydedildi" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Parola korumalı" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Send bağlantısını kopyala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Otomatik doldurma ayarları" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Kısayolu değiştir" + }, "autofillShortcut": { "message": "Otomatik doldurma klavye kısayolu" }, @@ -2970,10 +3048,18 @@ "message": "Eşleşen hesaplarınızı görmek için hesabınızın kilidini açın", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Otomatik doldurma önerilerini görmek için hesabınızın kilidini açın", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Hesap kilidini aç", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Bilgileri doldur", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Kasaya yeni kayıt ekle", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "Yeni hesap", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "Yeni kart", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden otomatik doldurma menüsü mevcut. Seçmek için aşağı ok tuşuna basın.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Geçersiz dosya parolası. Lütfen dışa aktardığınız dosyayı oluştururken girdiğiniz parolayı kullanın." }, - "importDestination": { - "message": "İçe aktarma hedefi" + "destination": { + "message": "Hedef" }, "learnAboutImportOptions": { "message": "İçe aktarma seçeneklerinizi öğrenin" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,6 +3461,30 @@ "message": "Sık kullanılan biçimler", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Tarayıcı ayarlarına gidilsin mi?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Yardım merkezine gitmek ister misiniz?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Bitwarden varsayılan parola yöneticiniz yapılsın mı?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Kopyalanacak değer yok" }, - "assignCollections": { - "message": "Koleksiyon ata" + "assignToCollections": { + "message": "Koleksiyonlara ata" }, "copyEmail": { "message": "E-postayı kopyala" @@ -3569,34 +3703,34 @@ "message": "Pasif kuruluşlardaki kayıtlara erişilemez. Destek almak için kuruluş sahibinizle iletişime geçin." }, "additionalInformation": { - "message": "Additional information" + "message": "Ek bilgiler" }, "itemHistory": { - "message": "Item history" + "message": "Öğe geçmişi" }, "lastEdited": { - "message": "Last edited" + "message": "Son düzenlenme" }, "ownerYou": { - "message": "Owner: You" + "message": "Sahibi: Siz" }, "linked": { - "message": "Linked" + "message": "Bağlandı" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Kopyalama başarılı" }, "upload": { - "message": "Upload" + "message": "Yükle" }, "addAttachment": { - "message": "Add attachment" + "message": "Dosya ekle" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "Maksimum dosya boyutu 500 MB'dir" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "$NAME$ dosyasını sil", "placeholders": { "name": { "content": "$1", @@ -3605,7 +3739,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "$NAME$ dosyasını indir", "placeholders": { "name": { "content": "$1", @@ -3614,7 +3748,7 @@ } }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "Bu dosyayı kalıcı olarak silmek istediğinizden emin misiniz?" }, "premium": { "message": "Premium" @@ -3635,7 +3769,7 @@ "message": "İletişim bilgileri" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "İndir - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "kart numarasının sonu", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Hesap bilgileri" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Yükleniyor" }, - "assign": { - "message": "Assign" + "data": { + "message": "Veri" }, - "bulkCollectionAssignmentDialogDescription": { + "assign": { + "message": "Ata" + }, + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3686,16 +3830,16 @@ } }, "addField": { - "message": "Add field" + "message": "Alan ekle" }, "add": { - "message": "Add" + "message": "Ekle" }, "fieldType": { - "message": "Field type" + "message": "Alan türü" }, "fieldLabel": { - "message": "Field label" + "message": "Alan etiketi" }, "textHelpText": { "message": "Use text fields for data like security questions" @@ -3713,7 +3857,7 @@ "message": "Enter the the field's html id, name, aria-label, or placeholder." }, "editField": { - "message": "Edit field" + "message": "Alanı düzenle" }, "editFieldLabel": { "message": "Edit $LABEL$", @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Kayıt konumu" } } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 6826e6fee14..67b478550ea 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Для доступу до сховища увійдіть в обліковий запис, або створіть новий." }, + "inviteAccepted": { + "message": "Запрошення прийнято" + }, "createAccount": { "message": "Створити обліковий запис" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Підказка для головного пароля (необов'язково)" }, + "joinOrganization": { + "message": "Приєднатися до організації" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Завершіть приєднання до цієї організації, встановивши головний пароль." + }, "tab": { "message": "Вкладка" }, @@ -612,7 +621,7 @@ "message": "Потрібний код підтвердження." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Автентифікацію було скасовано або вона тривала надто довго. Повторіть спробу." }, "invalidVerificationCode": { "message": "Недійсний код підтвердження" @@ -640,13 +649,13 @@ "message": "Скануйте QR-код програмою автентифікації" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Спростіть двоетапну перевірку" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden може автоматично заповнювати одноразові коди двоетапної перевірки. Скопіюйте і вставте ключ у це поле." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden може автоматично заповнювати одноразові коди двоетапної перевірки. Відкрийте камеру, щоб сканувати QR-код на цьому вебсайті, або скопіюйте і вставте ключ у це поле." }, "copyTOTP": { "message": "Скопіюйте ключ автентифікації (TOTP)" @@ -661,19 +670,19 @@ "message": "Тривалість вашого сеансу завершилась." }, "logIn": { - "message": "Log in" + "message": "Увійти" }, "restartRegistration": { - "message": "Restart registration" + "message": "Перезапустити реєстрацію" }, "expiredLink": { - "message": "Expired link" + "message": "Протерміноване посилання" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Перезапустіть реєстрацію або спробуйте ввійти." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Можливо, ви вже зареєстровані" }, "logOutConfirmation": { "message": "Ви дійсно хочете вийти?" @@ -736,6 +745,10 @@ "newUri": { "message": "Новий URI" }, + "addDomain": { + "message": "Додати домен", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Запис додано" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Запитувати про додавання запису" }, + "vaultSaveOptionsTitle": { + "message": "Параметри збереження до сховища" + }, "addLoginNotificationDesc": { "message": "Запитувати про додавання запису, якщо його немає у вашому сховищі." }, "addLoginNotificationDescAlt": { "message": "Запитувати про додавання запису, якщо такого не знайдено у вашому сховищі. Застосовується для всіх облікових записів, до яких виконано вхід." }, + "showCardsInVaultView": { + "message": "Показувати картки як пропозиції автозаповнення в режимі перегляду сховища" + }, "showCardsCurrentTab": { "message": "Показувати картки на вкладці" }, "showCardsCurrentTabDesc": { "message": "Показувати список карток на сторінці вкладки для легкого автозаповнення." }, + "showIdentitiesInVaultView": { + "message": "Показувати особисті дані як пропозиції автозаповнення в режимі перегляду сховища" + }, "showIdentitiesCurrentTab": { "message": "Показувати посвідчення на вкладці" }, @@ -1220,7 +1242,16 @@ "message": "Меню автозаповнення на полях форм", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Пропозиції автозаповнення" + }, + "showInlineMenuLabel": { + "message": "Пропозиції автозаповнення на полях форм" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Показувати пропозиції, якщо вибрано піктограму" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Застосовується для всіх облікових записів, до яких виконано вхід." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1241,17 +1272,36 @@ "message": "Якщо вибрано піктограму автозаповнення", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Автозаповнення на сторінці" + }, "enableAutoFillOnPageLoad": { "message": "Автозаповнення на сторінці" }, "enableAutoFillOnPageLoadDesc": { "message": "Якщо виявлено форму входу, автоматично заповнювати її під час завантаження вебсторінки." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Скомпрометовані або ненадійні вебсайти можуть використати функцію автозаповнення під час завантаження сторінки для завдання шкоди." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { - "message": "Дізнатися більше про автозаповнення" + "message": "Докладніше про автозаповнення" }, "defaultAutoFillOnPageLoad": { "message": "Типове налаштування автозаповнення для записів входу" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Логічне значення" }, + "cfTypeCheckbox": { + "message": "Прапорець" + }, "cfTypeLinked": { "message": "Пов'язано", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "Ваш новий головний пароль не задовольняє вимоги політики." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Отримуйте поради, оголошення та можливості дослідження від Bitwarden у своїй поштовій скриньці." }, "unsubscribe": { "message": "Відписатися" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "Політика організації заблокувала імпортування елементів до вашого особистого сховища." }, + "domainsTitle": { + "message": "Домени", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "Виключені домени" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden не запитуватиме про збереження даних входу для цих доменів для всіх облікових записів, до яких виконано вхід. Потрібно оновити сторінку для застосування змін." }, + "websiteItemLabel": { + "message": "Вебсайт $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ не є дійсним доменом", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Виняток для домену збережено" + }, "send": { "message": "Відправлення", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Захищено паролем" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Копіювати посилання відправлення", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "Налаштування автозаповнення" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "Комбінації клавіш автозаповнення" }, @@ -2790,11 +2868,11 @@ "message": "Довірений пристрій" }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "Немає активних відправлень", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendsNoItemsMessage": { - "message": "Use Send to securely share encrypted information with anyone.", + "message": "Використовуйте відправлення, щоб безпечно надавати доступ іншим до зашифрованої інформації.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "inputRequired": { @@ -2970,10 +3048,18 @@ "message": "Розблокуйте обліковий запис, щоб побачити відповідні записи", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "Розблокувати обліковий запис", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "Заповнити облікові дані для", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "Додати новий запис сховища", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Доступне меню автозаповнення Bitwarden. Натисніть клавішу стрілки для вибору.", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3081,7 +3191,7 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Помилка під'єднання до служби Duo. Скористайтеся іншим способом двоетапної перевірки або зверніться до служби підтримки Duo по допомогу." }, "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Запустіть Duo і виконайте дії для завершення входу." @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "Неправильний пароль файлу. Використайте пароль, який ви вводили під час створення експортованого файлу." }, - "importDestination": { - "message": "Призначення імпорту" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "Дізнайтеся про параметри імпорту" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Поширені формати", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Зробити Bitwarden типовим менеджером паролів?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Якщо ігнорувати цей параметр, можуть виникнути конфлікти автозаповнення між Bitwarden і браузером.", + "message": "Якщо ігнорувати цей параметр, можуть виникнути конфлікти пропозицій автозаповнення між Bitwarden і браузером.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "Немає значень для копіювання" }, - "assignCollections": { - "message": "Призначити збірки" + "assignToCollections": { + "message": "Призначити до збірок" }, "copyEmail": { "message": "Копіювати е-пошту" @@ -3626,13 +3760,13 @@ "message": "Фільтри" }, "personalDetails": { - "message": "Personal details" + "message": "Особисті дані" }, "identification": { - "message": "Identification" + "message": "Ідентифікація" }, "contactInfo": { - "message": "Contact info" + "message": "Контактні дані" }, "downloadAttachment": { "message": "Завантажити – $ITEMNAME$", @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "Облікові дані для входу" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Ключ автентифікації" }, "cardDetails": { "message": "Подробиці картки" @@ -3662,19 +3800,25 @@ } }, "addAccount": { - "message": "Add account" + "message": "Додати обліковий запис" }, "loading": { - "message": "Loading" + "message": "Завантаження" + }, + "data": { + "message": "Data" }, "assign": { - "message": "Assign" + "message": "Призначити" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Ви вибрали $TOTAL_COUNT$ записів. Ви не можете оновити $READONLY_COUNT$ записів, тому що у вас немає дозволу на редагування.", "placeholders": { "total_count": { "content": "$1", @@ -3686,37 +3830,37 @@ } }, "addField": { - "message": "Add field" + "message": "Додати поле" }, "add": { - "message": "Add" + "message": "Додати" }, "fieldType": { - "message": "Field type" + "message": "Тип поля" }, "fieldLabel": { - "message": "Field label" + "message": "Мітка поля" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Використовуйте текстові поля для даних, як-от секретні запитання" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Використовуйте приховані поля для конфіденційних даних, як-от пароль" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to auto-fill a form's checkbox, like a remember email" + "message": "Використовуйте прапорці, якщо хочете автоматично заповнювати поля, як-от адресу е-пошти" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing auto-fill issues for a specific website." + "message": "Використовуйте пов'язане поле у разі виникнення проблем з автозаповненням для певного вебсайту." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "Введіть html-ідентифікатор поля, назву, мітку або заповнювач." }, "editField": { - "message": "Edit field" + "message": "Редагувати поле" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "Редагувати $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3725,7 +3869,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "Видалити $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3734,7 +3878,7 @@ } }, "fieldAdded": { - "message": "$LABEL$ added", + "message": "$LABEL$ додано", "placeholders": { "label": { "content": "$1", @@ -3743,7 +3887,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "Перевпорядкувати $LABEL$. Використовуйте клавіші зі стрілками для переміщення.", "placeholders": { "label": { "content": "$1", @@ -3752,7 +3896,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ переміщено вгору, позиція $INDEX$ з $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3769,23 +3913,35 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Оберіть збірки для призначення" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 елемент буде остаточно перенесено до вибраної організації. Ви більше не будете власником цього елемента." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ елементи буде остаточно перенесено до вибраної організації. Ви більше не будете власником цих елементів.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 елемент буде остаточно перенесено до $ORG$. Ви більше не будете власником цього елемента.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ елементи буде остаточно перенесено до $ORG$. Ви більше не будете власником цих елементів.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3794,13 +3950,31 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Збірки успішно призначено" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Ви нічого не вибрали." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Вибрані записи переміщено до $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemsMovedToOrg": { + "message": "Елементи переміщено до $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Елемент переміщено до $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3809,7 +3983,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ переміщено вниз, позиція $INDEX$ з $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Розташування елемента" } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 44ca71922c2..04dd4495fb5 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -3,24 +3,27 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden - Trình Quản lý Mật khẩu", + "message": "Trình quản lý mật khẩu Bitwarden", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "Ở nhà, ở cơ quan, hay trên đường đi, Bitwarden sẽ bảo mật tất cả mật khẩu, passkey, và thông tin cá nhân của bạn", + "message": "Ở nhà, ở cơ quan, hay trên đường đi, Bitwarden sẽ bảo mật tất cả mật khẩu, mã khoá, và thông tin cá nhân của bạn", "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Đăng nhập hoặc tạo tài khoản mới để truy cập kho lưu trữ của bạn." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Tạo tài khoản" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Đặt mật khẩu mạnh" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Hoàn thành việc tạo tài khoản của bạn bằng cách đặt mật khẩu" }, "login": { "message": "Đăng nhập" @@ -50,7 +53,7 @@ "message": "Gợi ý mật khẩu chính có thể giúp bạn nhớ lại mật khẩu của mình nếu bạn quên nó." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Nếu bạn quên mật khẩu, gợi ý mật khẩu có thể được gửi tới email của bạn. $CURRENT$/$MAXIMUM$ ký tự tối đa.", "placeholders": { "current": { "content": "$1", @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Gợi ý mật khẩu chính (tùy chọn)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, @@ -192,19 +201,19 @@ "message": "Tiếp tục tới ứng dụng web?" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "Khám phá thêm các tính năng của tài khoản Bitwarden của bạn trên bản web." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "Đi đến Trung tâm trợ giúp?" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "Tìm hiểu thêm về cách sử dụng Bitwarden trong Trung tâm trợ giúp." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "Vẫn tiếp tục đến cửa hàng tiện ích mở rộng?" }, "continueToBrowserExtensionStoreDesc": { - "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." + "message": "Giúp người khác tìm hiểu xem Bitwarden có phù hợp với họ không. Hãy truy cập cửa hàng tiện ích mở rộng trên trình duyệt của bạn và đánh giá ngay bây giờ." }, "changeMasterPasswordOnWebConfirmation": { "message": "Bạn có thể thay đổi mật khẩu chính của mình trên Bitwarden bản web." @@ -224,43 +233,43 @@ "message": "Đăng xuất" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "Giới thiệu về Bitwarden" }, "about": { "message": "Thông tin" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "Thông tin khác từ Bitwarden" }, "continueToBitwardenDotCom": { - "message": "Continue to bitwarden.com?" + "message": "Vẫn tiếp tục đến bitwarden.com?" }, "bitwardenForBusiness": { - "message": "Bitwarden for Business" + "message": "Bitwarden dành cho Doanh Nghiệp" }, "bitwardenAuthenticator": { "message": "Bitwarden Authenticator" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website" + "message": "Ứng dụng Bitwarden Authenticator cho phép bạn lưu trữ khóa xác thực và tạo mã TOTP cho quy trình xác minh hai bước. Tìm hiểu thêm trên trang web bitwarden.com" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" }, "continueToSecretsManagerPageDesc": { - "message": "Securely store, manage, and share developer secrets with Bitwarden Secrets Manager. Learn more on the bitwarden.com website." + "message": "Lưu trữ bảo mật, quản lý và chia sẻ bí mật của nhà phát triển với Bitwarden Secrets Manager. Truy cập bitwarden.com để biết thêm chi tiết." }, "passwordlessDotDev": { "message": "Passwordless.dev" }, "continueToPasswordlessDotDevPageDesc": { - "message": "Create smooth and secure login experiences free from traditional passwords with Passwordless.dev. Learn more on the bitwarden.com website." + "message": "Tạo trải nghiệm đăng nhập mượt mà và an toàn không cần mật khẩu truyền thống với Passwordless.dev. Tìm hiểu thêm trên trang web bitwarden.com." }, "freeBitwardenFamilies": { - "message": "Free Bitwarden Families" + "message": "Gói Gia đình Miễn phí của Bitwarden" }, "freeBitwardenFamiliesPageDesc": { - "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." + "message": "Bạn đủ điều kiện cho Gói Gia đình Miễn phí của Bitwarden. Hãy nhận ưu đãi này ngay hôm nay trên ứng dụng web." }, "version": { "message": "Phiên bản" @@ -321,7 +330,7 @@ "message": "Tự động tạo mật khẩu mạnh mẽ, độc nhất cho đăng nhập của bạn." }, "bitWebVaultApp": { - "message": "Bitwarden web app" + "message": "Ứng dụng Bitwarden bản web" }, "importItems": { "message": "Nhập mục" @@ -409,13 +418,13 @@ "message": "Yêu thích" }, "unfavorite": { - "message": "Unfavorite" + "message": "Bỏ thích" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Đã thêm vào yêu thích" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Đã xóa khỏi yêu thích" }, "notes": { "message": "Ghi chú" @@ -439,7 +448,7 @@ "message": "Khởi chạy" }, "launchWebsite": { - "message": "Launch website" + "message": "Mở trang web" }, "website": { "message": "Trang web" @@ -454,7 +463,7 @@ "message": "Khác" }, "unlockMethods": { - "message": "Unlock options" + "message": "Tùy chọn mở khóa" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "Thiết lập phương thức mở khóa để thay đổi hành động hết thời gian chờ của vault." @@ -463,10 +472,10 @@ "message": "Thiết lập phương pháp mở khóa trong Cài đặt" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "Thời gian chờ của phiên" }, "otherOptions": { - "message": "Other options" + "message": "Tùy chọn khác" }, "rateExtension": { "message": "Đánh giá tiện ích mở rộng" @@ -557,16 +566,16 @@ "message": "Bảo mật" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "Nhập lại mật khẩu chính" }, "masterPassword": { - "message": "Master password" + "message": "Mật khẩu chính" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "Mật khẩu chính của bạn không thể phục hồi nếu bạn quên nó!" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "Gợi ý mật khẩu chính" }, "errorOccurred": { "message": "Đã xảy ra lỗi" @@ -612,7 +621,7 @@ "message": "Yêu cầu mã xác nhận." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Quá trình xác thực đã bị hủy hoặc mất quá nhiều thời gian. Vui lòng thử lại." }, "invalidVerificationCode": { "message": "Mã xác minh không đúng" @@ -640,13 +649,13 @@ "message": "Quét mã QR xác thực từ trang web hiện tại" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Thực hiện xác minh hai bước liền mạch" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden có thể lưu trữ và điền mã xác minh 2 bước. Sao chép và dán khóa vào trường này." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden có thể lưu trữ và điền mã xác minh 2 bước. Hãy chọn biểu tượng máy ảnh để chụp mã QR xác thực của trang web, hoặc sao chép và dán khoá vào ô này." }, "copyTOTP": { "message": "Sao chép khóa Authenticator (TOTP)" @@ -655,25 +664,25 @@ "message": "Đã đăng xuất" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Bạn đã đăng xuất khỏi tài khoản của mình." }, "loginExpired": { "message": "Phiên đăng nhập của bạn đã hết hạn." }, "logIn": { - "message": "Log in" + "message": "Đăng nhập" }, "restartRegistration": { - "message": "Restart registration" + "message": "Tiến hành đăng ký lại" }, "expiredLink": { - "message": "Expired link" + "message": "Liên kết đã hết hạn" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Vui lòng đăng ký lại hoặc thử đăng nhập." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Bạn có thể đã có tài khoản" }, "logOutConfirmation": { "message": "Bạn có chắc chắn muốn đăng xuất không?" @@ -736,6 +745,10 @@ "newUri": { "message": "URI mới" }, + "addDomain": { + "message": "Thêm tên miền", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "Đã thêm mục" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "Hỏi để thêm đăng nhập" }, + "vaultSaveOptionsTitle": { + "message": "Lưu vào các tùy chọn kho" + }, "addLoginNotificationDesc": { "message": "'Thông báo Thêm đăng nhập' sẽ tự động nhắc bạn lưu các đăng nhập mới vào hầm an toàn của bạn bất cứ khi nào bạn đăng nhập trang web lần đầu tiên." }, "addLoginNotificationDescAlt": { "message": "Đưa ra lựa chọn để thêm một mục nếu không tìm thấy mục đó trong hòm của bạn. Áp dụng với mọi tài khoản đăng nhập trên thiết bị." }, + "showCardsInVaultView": { + "message": "Hiển thị các thẻ như các gợi ý tự động điền trên giao diện kho" + }, "showCardsCurrentTab": { "message": "Hiển thị thẻ trên trang Tab" }, "showCardsCurrentTabDesc": { "message": "Liệt kê các mục thẻ trên trang Tab để dễ dàng tự động điền." }, + "showIdentitiesInVaultView": { + "message": "Hiển thị các danh tính như các gợi ý tự động điền trên giao diện kho" + }, "showIdentitiesCurrentTab": { "message": "Hiển thị danh tính trên trang Tab" }, @@ -818,10 +840,10 @@ "message": "Đưa ra lựa chọn để cập nhật mật khẩu khi phát hiện có sự thay đổi trên trang web. Áp dụng với mọi tài khoản đăng nhập trên thiết bị." }, "enableUsePasskeys": { - "message": "Đưa ra lựa chọn để lưu và sử dụng passkey" + "message": "Đưa ra lựa chọn để lưu và sử dụng mã khoá" }, "usePasskeysDesc": { - "message": "Đưa ra lựa chọn để lưu passkey mới hoặc đăng nhập bằng passkey đã lưu trong hòm. Áp dụng với mọi tài khoản đăng nhập trên thiết bị." + "message": "Đưa ra lựa chọn để lưu mã khoá mới hoặc đăng nhập bằng mã khoá đã lưu trong kho. Áp dụng với mọi tài khoản đăng nhập trên thiết bị." }, "notificationChangeDesc": { "message": "Bạn có muốn cập nhật mật khẩu này trên Bitwarden không?" @@ -836,7 +858,7 @@ "message": "Mở khóa" }, "additionalOptions": { - "message": "Additional options" + "message": "Tùy chọn bổ sung" }, "enableContextMenuItem": { "message": "Hiển thị tuỳ chọn menu ngữ cảnh" @@ -876,7 +898,7 @@ "description": "'Solarized' is a noun and the name of a color scheme. It should not be translated." }, "exportFrom": { - "message": "Export from" + "message": "Xuất từ" }, "exportVault": { "message": "Xuất kho lưu trữ" @@ -885,28 +907,28 @@ "message": "File Format" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "Tập tin này sẽ được bảo vệ bằng mật khẩu và yêu cầu mật khẩu để giải mã." }, "filePassword": { - "message": "File password" + "message": "Mật khẩu tập tin" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "message": "Mật khẩu này sẽ được sử dụng để xuất và nhập tập tin này" }, "accountRestrictedOptionDescription": { - "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account." + "message": "Sử dụng khóa mã hóa tài khoản của bạn, được tạo từ tên người dùng và mật khẩu chính của bạn để mã hóa tệp xuất và giới hạn việc nhập chỉ cho tài khoản Bitwarden hiện tại." }, "passwordProtectedOptionDescription": { - "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." + "message": "Thiết lập mật khẩu cho tệp để mã hóa dữ liệu xuất và nhập nó vào bất kỳ tài khoản Bitwarden nào bằng cách sử dụng mật khẩu đó để giải mã." }, "exportTypeHeading": { - "message": "Export type" + "message": "Loại xuất" }, "accountRestricted": { - "message": "Account restricted" + "message": "Tài khoản bị hạn chế" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "“Mật khẩu tập tin” và “Nhập lại mật khẩu tập tin” không khớp." }, "warning": { "message": "CẢNH BÁO", @@ -922,7 +944,7 @@ "message": "Quá trình xuất này sẽ mã hóa dữ liệu của bạn bằng khóa mã hóa của tài khoản. Nếu bạn từng xoay khóa mã hóa tài khoản của mình, bạn nên xuất lại vì bạn sẽ không thể giải mã tệp xuất này." }, "encExportAccountWarningDesc": { - "message": "Các khóa mã hóa tài khoản là duy nhất cho mỗi tài khoản người dùng Bitwarden, vì vậy bạn không thể nhập một bản xuất được mã hóa vào một tài khoản khác." + "message": "Khóa mã hóa tài khoản là duy nhất cho mỗi tài khoản Bitwarden, vì vậy bạn không thể nhập tệp xuất được mã hóa vào một tài khoản khác." }, "exportMasterPassword": { "message": "Nhập mật khẩu chính để xuất kho lưu trữ của bạn." @@ -931,7 +953,7 @@ "message": "Đã chia sẻ" }, "bitwardenForBusinessPageDesc": { - "message": "Bitwarden for Business allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website." + "message": "Bitwarden cho Doanh Nghiệp cho phép bạn chia sẻ các mục trong kho mật khẩu với người khác bằng cách tạo một tổ chức. Tìm hiểu thêm trên bitwarden.com." }, "moveToOrganization": { "message": "Di chuyển đến tổ chức" @@ -1001,7 +1023,7 @@ "message": "Tính năng không có sẵn" }, "encryptionKeyMigrationRequired": { - "message": "Encryption key migration required. Please login through the web vault to update your encryption key." + "message": "Cần di chuyển khóa mã hóa. Vui lòng đăng nhập trang web Bitwaden để cập nhật khóa mã hóa của bạn." }, "premiumMembership": { "message": "Thành viên Cao Cấp" @@ -1025,7 +1047,7 @@ "message": "1GB bộ nhớ lưu trữ tập tin được mã hóa." }, "premiumSignUpTwoStepOptions": { - "message": "Proprietary two-step login options such as YubiKey and Duo." + "message": "Các tùy chọn xác minh hai bước như YubiKey và Duo." }, "ppremiumSignUpReports": { "message": "Thanh lọc mật khẩu, kiểm tra an toàn tài khoản và các báo cáo rò rĩ dữ liệu là để giữ cho kho của bạn an toàn." @@ -1145,17 +1167,17 @@ "message": "Ứng dụng Authenticator" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Nhập mã được tạo bởi ứng dụng xác thực như Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "Khóa bảo mật OTP Yubico" }, "yubiKeyDesc": { "message": "Sử dụng YubiKey để truy cập tài khoản của bạn. Hoạt động với thiết bị YubiKey 4, 4 Nano, 4C và NEO." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Nhập mã được tạo bởi Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1172,7 +1194,7 @@ "message": "Email" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "Nhập mã được gửi về email của bạn." }, "selfHostedEnvironment": { "message": "Môi trường tự lưu trữ" @@ -1181,13 +1203,13 @@ "message": "Chỉ định liên kết cơ bản của cài đặt bitwarden tại chỗ của bạn." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Nhập địa chỉ cơ sở của bản cài đặt Bitwarden được lưu trữ tại máy chủ của bạn. Ví dụ: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Đối với cấu hình nâng cao. Bạn có thể chỉ định địa chỉ cơ sở của mỗi dịch vụ một cách độc lập." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Bạn phải thêm địa chỉ máy chủ cơ sở hoặc ít nhất một môi trường tùy chỉnh." }, "customEnvironment": { "message": "Môi trường tùy chỉnh" @@ -1220,7 +1242,16 @@ "message": "Hiển thị menu tự động điền trên các trường biểu mẫu", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "Các gợi ý điền tự động" + }, + "showInlineMenuLabel": { + "message": "Hiển thị các gợi ý tự động điền trên các trường biểu mẫu" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Hiện gợi ý khi nhấp vào biểu tượng" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "Áp dụng cho tất cả tài khoản đã đăng nhập." }, "turnOffBrowserBuiltInPasswordManagerSettings": { @@ -1234,22 +1265,41 @@ "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "Khi trường được chọn (khi bấm vào)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { "message": "Khi chọn biểu tượng tự động điền", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Tự động điền khi tải trang" + }, "enableAutoFillOnPageLoad": { "message": "Tự động điền khi tải trang" }, "enableAutoFillOnPageLoadDesc": { "message": "Nếu phát hiện biểu mẫu đăng nhập, thực hiện tự động điền khi trang web tải xong." }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Cảnh báo:$CLOSETAG$ Các trang web bị xâm phạm hoặc không đáng tin cậy có thể lợi dụng tính năng tự động điền khi trang web được tải.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "Các trang web bị xâm phạm hoặc không đáng tin cậy có thể khai thác tính năng tự động điền khi tải trang." }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Tìm hiểu thêm về rủi ro" + }, "learnMoreAboutAutofill": { "message": "Tìm hiểu thêm về tự động điền" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "Đúng/Sai" }, + "cfTypeCheckbox": { + "message": "Ô tích chọn" + }, "cfTypeLinked": { "message": "Đã liên kết", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1493,7 +1546,7 @@ "message": "Danh tính" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "$TYPE$ mới", "placeholders": { "type": { "content": "$1", @@ -1502,7 +1555,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Chỉnh sửa $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1511,7 +1564,7 @@ } }, "viewItemHeader": { - "message": "View $TYPE$", + "message": "Xem $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1529,7 +1582,7 @@ "message": "Bộ sưu tập" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ bộ sưu tập", "placeholders": { "count": { "content": "$1", @@ -1650,7 +1703,7 @@ "description": "ex. Date this password was updated" }, "neverLockWarning": { - "message": "Bạn có chắc bạn muốn sử dụng tùy chọn \"Không bao giờ\"? Đặt các tùy chọn khóa về \"Không bao giờ\" sẽ lưu key mã hóa kho của ngay trên thiết bị của bạn. Nếu bạn sử dụng tùy chọn này, bạn nên chắc chắn là thiết bị bạn đang được bảo vệ." + "message": "Bạn có chắc chắn muốn chọn \"Không bao giờ\" không? Lựa chọn này sẽ lưu khóa mã hóa kho của bạn trực tiếp trên thiết bị. Hãy nhớ bảo vệ thiết bị của bạn thật cẩn thận nếu bạn chọn tùy chọn này." }, "noOrganizationsList": { "message": "You do not belong to any organizations. Organizations allow you to securely share items with other users." @@ -1723,7 +1776,7 @@ "message": "Tạo bản sao" }, "passwordGeneratorPolicyInEffect": { - "message": "Có một hoặc vài chính sách của tổ chức đang làm ảnh hưởng đến cài đặt tạo mật khẩu của bạn." + "message": "Các chính sách của tổ chức đang ảnh hưởng đến cài đặt tạo mật khẩu của bạn." }, "vaultTimeoutAction": { "message": "Hành động khi hết thời gian chờ của kho lưu trữ" @@ -1755,7 +1808,7 @@ "message": "Mục đã được khôi phục" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "Bạn đã có tài khoản?" }, "vaultTimeoutLogOutConfirmation": { "message": "Việc đăng xuất sẽ loại bỏ tất cả truy cập vào kho lưu trữ của bạn và yêu cầu xác minh trực tuyến sau khi hết giai đoạn thời gian chờ. Bạn có chắc chắn muốn dùng cài đặt này không?" @@ -1767,7 +1820,7 @@ "message": "Tự động điền và Lưu" }, "fillAndSave": { - "message": "Fill and save" + "message": "Điền và lưu" }, "autoFillSuccessAndSavedUri": { "message": "Đã tự động điền mục và lưu URI" @@ -1848,19 +1901,19 @@ "message": "Mật khẩu chính bạn chọn không đáp ứng yêu cầu." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Nhận lời khuyên, thông báo và cơ hội nghiên cứu từ Bitwarden trong hộp thư đến của bạn." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Huỷ đăng ký" }, "atAnyTime": { - "message": "at any time." + "message": "bất cứ lúc nào." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Bằng cách tiếp tục, bạn đồng ý" }, "and": { - "message": "and" + "message": "và" }, "acceptPolicies": { "message": "Bạn đồng ý với những điều sau khi nhấn chọn ô này:" @@ -1881,10 +1934,10 @@ "message": "Ok" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Lỗi làm mới khoá truy cập" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Bạn có thể đã bị đăng xuất. Vui lòng đăng xuất và đăng nhập lại." }, "desktopSyncVerificationTitle": { "message": "Xác minh đồng bộ máy tính" @@ -1935,16 +1988,16 @@ "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": "User locked or logged out" + "message": "Người dùng đã khoá hoặc đã đăng xuất" }, "biometricsNotUnlockedDesc": { - "message": "Please unlock this user in the desktop application and try again." + "message": "Vui lòng mở khóa người dùng này trong ứng dụng máy tính và thử lại." }, "biometricsFailedTitle": { - "message": "Biometrics failed" + "message": "Sinh trắc học không thành công" }, "biometricsFailedDesc": { - "message": "Biometrics cannot be completed, consider using a master password or logging out. If this persists, please contact Bitwarden support." + "message": "Không thể hoàn thành sinh trắc học, hãy cân nhắc sử dụng mật khẩu chính hoặc đăng xuất. Nếu sự cố vẫn tiếp diễn, vui lòng liên hệ bộ phận hỗ trợ của Bitwarden." }, "nativeMessaginPermissionErrorTitle": { "message": "Quyền chưa được cấp" @@ -1965,7 +2018,11 @@ "message": "Chính sách của tổ chức đang ảnh hưởng đến các tùy chọn quyền sở hữu của bạn." }, "personalOwnershipPolicyInEffectImports": { - "message": "An organization policy has blocked importing items into your individual vault." + "message": "Chính sách của tổ chức đã chặn việc nhập các mục vào kho cá nhân của bạn." + }, + "domainsTitle": { + "message": "Các tên miền", + "description": "A category title describing the concept of web domains" }, "excludedDomains": { "message": "Tên miền đã loại trừ" @@ -1974,17 +2031,29 @@ "message": "Bitwarden sẽ không yêu cầu lưu thông tin đăng nhập cho các miền này. Bạn phải làm mới trang để các thay đổi có hiệu lực." }, "excludedDomainsDescAlt": { - "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." + "message": "Bitwarden sẽ không yêu cầu lưu thông tin đăng nhập cho các miền này. Bạn phải làm mới trang để các thay đổi có hiệu lực." + }, + "websiteItemLabel": { + "message": "Trang Web $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ không phải là tên miền hợp lệ", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Các thay đổi tên miền loại trừ đã được lưu" + }, "send": { "message": "Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "Mật khẩu đã được bảo vệ" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "Sao chép liên kết mục Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2115,7 +2187,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", + "message": "Vô hiệu hoá mục Gửi này để không ai có thể truy cập nó.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendShareDesc": { @@ -2156,19 +2228,19 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { - "message": "In order to choose a file, open the extension in the sidebar (if possible) or pop out to a new window by clicking this banner." + "message": "Để chọn tập tin, mở tiện ích mở rộng trong thanh bên (nếu có thể) hoặc mở ra cửa sổ mới bằng cách nhấp vào biểu ngữ này." }, "sendFirefoxFileWarning": { - "message": "In order to choose a file using Firefox, open the extension in the sidebar or pop out to a new window by clicking this banner." + "message": "Để chọn tập tin bằng Firefox, mở tiện ích mở rộng trong thanh bên hoặc mở ra cửa sổ mới bằng cách nhấp vào biểu ngữ này." }, "sendSafariFileWarning": { - "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." + "message": "Để chọn tập tin bằng Safari, mở ra cửa sổ mới bằng cách nhấp vào biểu ngữ này." }, "sendFileCalloutHeader": { "message": "Trước khi bạn bắt đầu" }, "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", + "message": "Để dùng bộ chọn ngày dạng lịch", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" }, "sendFirefoxCustomDatePopoutMessage2": { @@ -2176,29 +2248,29 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" }, "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", + "message": "để bật cửa sổ của bạn ra.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" }, "expirationDateIsInvalid": { - "message": "The expiration date provided is not valid." + "message": "Ngày hết hạn bạn nhập không hợp lệ." }, "deletionDateIsInvalid": { - "message": "The deletion date provided is not valid." + "message": "Ngày xóa bạn nhập không hợp lệ." }, "expirationDateAndTimeRequired": { - "message": "An expiration date and time are required." + "message": "Ngày và giờ hết hạn là bắt buộc." }, "deletionDateAndTimeRequired": { - "message": "A deletion date and time are required." + "message": "Ngày và giờ xóa là bắt buộc." }, "dateParsingError": { - "message": "There was an error saving your deletion and expiration dates." + "message": "Đã xảy ra lỗi khi lưu ngày xoá và ngày hết hạn của bạn." }, "hideEmail": { - "message": "Hide my email address from recipients." + "message": "Ẩn địa chỉ email của tôi khỏi người nhận." }, "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." + "message": "Các chính sách của tổ chức đang ảnh hưởng đến tùy chọn Gửi của bạn." }, "passwordPrompt": { "message": "Nhắc lại mật khẩu chính" @@ -2213,7 +2285,7 @@ "message": "Yêu cầu xác nhận danh tính qua email" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "Email đã xác minh" }, "emailVerificationRequiredDesc": { "message": "Bạn phải xác nhận email để sử dụng tính năng này. Bạn có thể xác minh email trên web." @@ -2225,34 +2297,34 @@ "message": "Cập nhật mật khẩu chính" }, "updateMasterPasswordWarning": { - "message": "Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "Mật khẩu chính của bạn gần đây đã được thay đổi bởi người quản trị trong tổ chức của bạn. Để truy cập kho, bạn phải cập nhật nó ngay bây giờ. Việc tiếp tục sẽ đăng xuất khỏi kho và bạn sẽ cần đăng nhập lại. Ứng dụng Bitwaden trên các thiết bị khác có thể tiếp tục hoạt động trong tối đa một giờ sau đó sẽ bị đăng xuất." }, "updateWeakMasterPasswordWarning": { - "message": "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "Mật khẩu chính của bạn không đáp ứng chính sách tổ chức của bạn. Để truy cập kho, bạn phải cập nhật mật khẩu chính của mình ngay bây giờ. Việc tiếp tục sẽ đăng xuất bạn khỏi phiên hiện tại và bắt buộc đăng nhập lại. Các phiên hoạt động trên các thiết bị khác có thể tiếp tục duy trì hoạt động trong tối đa một giờ." }, "resetPasswordPolicyAutoEnroll": { - "message": "Automatic enrollment" + "message": "Đăng ký tự động" }, "resetPasswordAutoEnrollInviteWarning": { - "message": "This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password." + "message": "Tổ chức này có chính sách doanh nghiệp sẽ tự động đặt lại mật khẩu chính cho bạn. Đăng ký sẽ cho phép quản trị viên tổ chức thay đổi mật khẩu chính của bạn." }, "selectFolder": { "message": "Chọn thư mục..." }, "noFoldersFound": { - "message": "No folders found", + "message": "Không tìm thấy thư mục nào", "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { - "message": "Your organization permissions were updated, requiring you to set a master password.", + "message": "Quyền tổ chức của bạn đã được cập nhật, yêu cầu bạn đặt mật khẩu chính.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "orgRequiresYouToSetPassword": { - "message": "Your organization requires you to set a master password.", + "message": "Tổ chức của bạn yêu cầu bạn đặt mật khẩu chính.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { - "message": "Verification required", + "message": "Yêu cầu xác minh", "description": "Default title for the user verification dialog." }, "hours": { @@ -2262,7 +2334,7 @@ "message": "Phút" }, "vaultTimeoutPolicyInEffect": { - "message": "Your organization policies have set your maximum allowed vault timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "message": "Tổ chức của bạn đã đặt thời gian mở kho tối đa là $HOURS$ giờ và $MINUTES$ phút.", "placeholders": { "hours": { "content": "$1", @@ -2275,7 +2347,7 @@ } }, "vaultTimeoutPolicyWithActionInEffect": { - "message": "Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is $HOURS$ hour(s) and $MINUTES$ minute(s). Your vault timeout action is set to $ACTION$.", + "message": "Tổ chức của bạn đang ảnh hưởng đến thời gian mở kho. Thời gian mở kho tối đa là $HOURS$ giờ và $MINUTES$ phút. Kho sẽ $ACTION$ sau khi hết thời gian mở kho.", "placeholders": { "hours": { "content": "$1", @@ -2292,7 +2364,7 @@ } }, "vaultTimeoutActionPolicyInEffect": { - "message": "Your organization policies have set your vault timeout action to $ACTION$.", + "message": "Tổ chức của bạn sẽ $ACTION$ sau khi hết thời gian mở kho.", "placeholders": { "action": { "content": "$1", @@ -2301,19 +2373,19 @@ } }, "vaultTimeoutTooLarge": { - "message": "Your vault timeout exceeds the restrictions set by your organization." + "message": "Thời gian mở kho vượt quá giới hạn do tổ chức của bạn đặt ra." }, "vaultExportDisabled": { "message": "Xuất kho lưu trữ không có sẵn" }, "personalVaultExportPolicyInEffect": { - "message": "One or more organization policies prevents you from exporting your individual vault." + "message": "Các chính sách của tổ chức ngăn cản bạn xuất kho lưu trữ cá nhân của mình." }, "copyCustomFieldNameInvalidElement": { - "message": "Unable to identify a valid form element. Try inspecting the HTML instead." + "message": "Không thể xác định được phần tử biểu mẫu hợp lệ. Thay vào đó hãy thử kiểm tra trong HTML." }, "copyCustomFieldNameNotUnique": { - "message": "No unique identifier found." + "message": "Không tìm thấy danh tính duy nhất." }, "convertOrganizationEncryptionDesc": { "message": "$ORGANIZATION$ hiện đang dùng SSO với khoá máy chủ tự lưu trữ. Từ giờ không cần mật khẩu chính để đăng nhập vào tổ chức này nữa.", @@ -2343,13 +2415,13 @@ "message": "Bật tắt đếm kí tự" }, "sessionTimeout": { - "message": "Your session has timed out. Please go back and try logging in again." + "message": "Phiên đăng nhập của bạn đã hết hạn. Vui lòng quay trở lại và thử đăng nhập lại." }, "exportingPersonalVaultTitle": { - "message": "Exporting individual vault" + "message": "Đang xuất dữ liệu kho cá nhân" }, "exportingIndividualVaultDescription": { - "message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.", + "message": "Chỉ dữ liệu trong kho cá nhân liên kết với $EMAIL$ mới được xuất. Không bao gồm \ncác dữ liệu trong kho tổ chức. Chỉ thông tin mục kho mới được xuất, sẽ không có các tệp đính kèm.", "placeholders": { "email": { "content": "$1", @@ -2358,10 +2430,10 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "Đang xuất dữ liệu kho tổ chức" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "Chỉ dữ liệu trong kho tổ chức $ORGANIZATION$ mới được xuất. Các kho cá nhân hoặc của tổ chức khác sẽ không được bao gồm.", "placeholders": { "organization": { "content": "$1", @@ -2386,13 +2458,13 @@ "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "Use your email provider's sub-addressing capabilities." + "message": "Sử dụng khả năng địa chỉ phụ của nhà cung cấp dịch vụ mail của bạn." }, "catchallEmail": { "message": "Email Catch-all" }, "catchallEmailDesc": { - "message": "Use your domain's configured catch-all inbox." + "message": "Sử dụng hộp thư bạn đã thiết lập để nhận tất cả email gửi đến tên miền của bạn." }, "random": { "message": "Ngẫu nhiên" @@ -2413,13 +2485,13 @@ "message": "Dịch vụ" }, "forwardedEmail": { - "message": "Forwarded email alias" + "message": "Đã chuyển tiếp bí danh email" }, "forwardedEmailDesc": { - "message": "Generate an email alias with an external forwarding service." + "message": "Tạo bí danh email với dịch vụ chuyển tiếp bên ngoài." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "Lỗi $SERVICENAME$: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -2433,11 +2505,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Được tạo bởi Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Trang web: $WEBSITE$. Được tạo bởi Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -2447,7 +2519,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Khoá API $SERVICENAME$ không hợp lệ", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2457,7 +2529,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Khoá API $SERVICENAME$ không hợp lệ: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2471,7 +2543,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "Không thể lấy ID tài khoản email ẩn từ $SERVICENAME$.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2481,7 +2553,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Tên miền $SERVICENAME$ không hợp lệ.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -2491,7 +2563,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Địa chỉ $SERVICENAME$ không hợp lệ.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -2501,7 +2573,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "$SERVICENAME$ đã xảy ra lỗi không xác định.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -2511,7 +2583,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "Người chuyển tiếp không xác định: '$SERVICENAME$'.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -2531,16 +2603,16 @@ "message": "Khóa API" }, "ssoKeyConnectorError": { - "message": "Key connector error: make sure key connector is available and working correctly." + "message": "Lỗi kết nối khóa: hãy đảm bảo kết nối khóa khả dụng và hoạt động chính xác." }, "premiumSubcriptionRequired": { - "message": "Premium subscription required" + "message": "Yêu cầu đăng ký gói Premium" }, "organizationIsDisabled": { - "message": "Organization suspended." + "message": "Tổ chức đã ngưng hoạt động." }, "disabledOrganizationFilterError": { - "message": "Items in suspended Organizations cannot be accessed. Contact your Organization owner for assistance." + "message": "Không thể truy cập các mục trong tổ chức đã ngưng hoạt động. Hãy liên hệ với chủ sở hữu tổ chức để được hỗ trợ." }, "loggingInTo": { "message": "Đang đăng nhập vào $DOMAIN$", @@ -2564,13 +2636,13 @@ "message": "Phiên bản máy chủ" }, "selfHostedServer": { - "message": "self-hosted" + "message": "tự lưu trữ" }, "thirdParty": { "message": "Bên thứ ba" }, "thirdPartyServerMessage": { - "message": "Connected to third-party server implementation, $SERVERNAME$. Please verify bugs using the official server, or report them to the third-party server.", + "message": "Bạn đang kết nối đến máy chủ $SERVERNAME$ của bên thứ ba. Vui lòng kiểm tra lỗi bằng cách sử dụng máy chủ chính thức hoặc báo lỗi cho bên thứ ba.", "placeholders": { "servername": { "content": "$1", @@ -2606,13 +2678,13 @@ "message": "Đăng nhập bằng thiết bị" }, "loginWithDeviceEnabledInfo": { - "message": "Log in with device must be set up in the settings of the Bitwarden app. Need another option?" + "message": "Đăng nhập bằng thiết bị phải được thiết lập trong cài đặt của ứng dụng Bitwarden. Dùng cách khác?" }, "fingerprintPhraseHeader": { "message": "Cụm từ dấu vân tay" }, "fingerprintMatchInfo": { - "message": "Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device." + "message": "Vui lòng đảm bảo rằng bạn đã mở khoá kho và cụm từ mật khẩu khớp trên thiết bị khác." }, "resendNotification": { "message": "Gửi lại thông báo" @@ -2624,28 +2696,28 @@ "message": "Một thông báo đã được gửi đến thiết bị của bạn." }, "loginInitiated": { - "message": "Login initiated" + "message": "Bắt đầu đăng nhập" }, "exposedMasterPassword": { "message": "Mật khẩu chính bị lộ" }, "exposedMasterPasswordDesc": { - "message": "Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?" + "message": "Mật khẩu này đã bị rò rỉ trong một vụ tấn công dữ liệu. Dùng mật khẩu mới và an toàn để bảo vệ tài khoản bạn. Bạn có chắc muốn sử dụng mật khẩu đã bị rò rỉ?" }, "weakAndExposedMasterPassword": { - "message": "Weak and Exposed Master Password" + "message": "Mật khẩu chính Yếu và Bị Lộ" }, "weakAndBreachedMasterPasswordDesc": { - "message": "Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?" + "message": "Mật khẩu yếu này đã bị rò rỉ trong một vụ tấn công dữ liệu. Dùng mật khẩu mới và an toàn để bảo vệ tài khoản bạn. Bạn có chắc muốn sử dụng mật khẩu đã bị rò rỉ?" }, "checkForBreaches": { - "message": "Check known data breaches for this password" + "message": "Kiểm tra mật khẩu có lộ trong các vụ rò rỉ dữ liệu hay không" }, "important": { "message": "Quan trọng:" }, "masterPasswordHint": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "Mật khẩu chính của bạn không thể phục hồi nếu bạn quên nó!" }, "characterMinimum": { "message": "$LENGTH$ ký tự tối thiểu", @@ -2663,7 +2735,7 @@ "message": "Cách tự đồng điền" }, "autofillSelectInfoWithCommand": { - "message": "Select an item from this screen, use the shortcut $COMMAND$, or explore other options in settings.", + "message": "Chọn một mục từ màn hình này, sử dụng phím tắt $COMMAND$, hoặc khám phá các tùy chọn khác trong cài đặt.", "placeholders": { "command": { "content": "$1", @@ -2672,14 +2744,20 @@ } }, "autofillSelectInfoWithoutCommand": { - "message": "Select an item from this screen, or explore other options in settings." + "message": "Chọn một mục từ màn hình này, hoặc khám phá các tùy chọn khác trong cài đặt." }, "gotIt": { - "message": "Got it" + "message": "Đã hiểu" }, "autofillSettings": { "message": "Cài đặt tự động điền" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Phím tắt tự động điền" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Thay đổi phím tắt" + }, "autofillShortcut": { "message": "Phím tắt tự động điền" }, @@ -2705,109 +2783,109 @@ } }, "loggingInOn": { - "message": "Logging in on" + "message": "Đang đăng nhập vào" }, "opensInANewWindow": { - "message": "Opens in a new window" + "message": "Mở trong cửa sổ mới" }, "deviceApprovalRequired": { - "message": "Device approval required. Select an approval option below:" + "message": "Yêu cầu phê duyệt thiết bị. Chọn một tuỳ chọn phê duyệt bên dưới:" }, "rememberThisDevice": { - "message": "Remember this device" + "message": "Lưu thiết bị này" }, "uncheckIfPublicDevice": { - "message": "Uncheck if using a public device" + "message": "Bỏ chọn nếu sử dụng thiết bị công cộng" }, "approveFromYourOtherDevice": { - "message": "Approve from your other device" + "message": "Phê duyệt bằng thiết bị khác" }, "requestAdminApproval": { - "message": "Request admin approval" + "message": "Yêu cầu quản trị viên phê duyệt" }, "approveWithMasterPassword": { - "message": "Approve with master password" + "message": "Phê duyệt bằng mật khẩu chính" }, "ssoIdentifierRequired": { - "message": "Organization SSO identifier is required." + "message": "Cần có mã định danh SSO của tổ chức." }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Đang tạo tài khoản trên" }, "checkYourEmail": { - "message": "Check your email" + "message": "Kiểm tra email của bạn" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Nhấp vào liên kết trong email được gửi đến" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "và tiếp tục tạo tài khoản của bạn." }, "noEmail": { - "message": "No email?" + "message": "Không có email?" }, "goBack": { - "message": "Go back" + "message": "Quay lại" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "để chỉnh sửa địa chỉ email của bạn." }, "eu": { - "message": "EU", + "message": "Châu Âu", "description": "European Union" }, "accessDenied": { - "message": "Access denied. You do not have permission to view this page." + "message": "Truy cập bị từ chối. Bạn không có quyền xem trang này." }, "general": { - "message": "General" + "message": "Chung" }, "display": { - "message": "Display" + "message": "Hiển thị" }, "accountSuccessfullyCreated": { - "message": "Account successfully created!" + "message": "Tạo tài khoản thành công!" }, "adminApprovalRequested": { - "message": "Admin approval requested" + "message": "Yêu cầu quản trị viên phê duyệt" }, "adminApprovalRequestSentToAdmins": { - "message": "Your request has been sent to your admin." + "message": "Yêu cầu của bạn đã được gửi đến quản trị viên." }, "youWillBeNotifiedOnceApproved": { - "message": "You will be notified once approved." + "message": "Bạn sẽ có thông báo nếu được phê duyệt." }, "troubleLoggingIn": { - "message": "Trouble logging in?" + "message": "Không thể đăng nhập?" }, "loginApproved": { - "message": "Login approved" + "message": "Lượt đăng nhập đã duyệt" }, "userEmailMissing": { - "message": "User email missing" + "message": "Thiếu email người dùng" }, "deviceTrusted": { - "message": "Device trusted" + "message": "Thiết bị tin cậy" }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "Không có mục Gửi nào đang hoạt động", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendsNoItemsMessage": { - "message": "Use Send to securely share encrypted information with anyone.", + "message": "Sử dụng Gửi để chia sẻ thông tin mã hóa một cách an toàn với bất kỳ ai.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "inputRequired": { - "message": "Input is required." + "message": "Trường này là bắt buộc." }, "required": { - "message": "required" + "message": "bắt buộc" }, "search": { - "message": "Search" + "message": "Tìm kiếm" }, "inputMinLength": { - "message": "Input must be at least $COUNT$ characters long.", + "message": "Giá trị nhập vào phải ít nhất $COUNT$ ký tự.", "placeholders": { "count": { "content": "$1", @@ -2816,7 +2894,7 @@ } }, "inputMaxLength": { - "message": "Input must not exceed $COUNT$ characters in length.", + "message": "Giá trị nhập vào không được vượt quá $COUNT$ ký tự.", "placeholders": { "count": { "content": "$1", @@ -2825,7 +2903,7 @@ } }, "inputForbiddenCharacters": { - "message": "The following characters are not allowed: $CHARACTERS$", + "message": "Các ký tự sau không được phép sử dụng: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -2834,7 +2912,7 @@ } }, "inputMinValue": { - "message": "Input value must be at least $MIN$.", + "message": "Giá trị nhập vào phải ít nhất $MIN$.", "placeholders": { "min": { "content": "$1", @@ -2843,7 +2921,7 @@ } }, "inputMaxValue": { - "message": "Input value must not exceed $MAX$.", + "message": "Giá trị nhập vào không được vượt quá $MAX$.", "placeholders": { "max": { "content": "$1", @@ -2852,17 +2930,17 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "Có ít nhất 1 địa chỉ email không hợp lệ" }, "inputTrimValidator": { - "message": "Input must not contain only whitespace.", + "message": "Giá trị nhập vào không được chỉ có khoảng trắng.", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "Input is not an email address." + "message": "Giá trị nhập vào không phải là địa chỉ email." }, "fieldsNeedAttention": { - "message": "$COUNT$ field(s) above need your attention.", + "message": "Có $COUNT$ trường cần bạn xem xét ở trên.", "placeholders": { "count": { "content": "$1", @@ -2871,22 +2949,22 @@ } }, "selectPlaceholder": { - "message": "-- Select --" + "message": "-- Chọn --" }, "multiSelectPlaceholder": { - "message": "-- Type to filter --" + "message": "-- Nhập để lọc --" }, "multiSelectLoading": { - "message": "Retrieving options..." + "message": "Đang tải các tuỳ chọn..." }, "multiSelectNotFound": { - "message": "No items found" + "message": "Không tìm thấy mục nào" }, "multiSelectClearAll": { - "message": "Clear all" + "message": "Xoá tất cả" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ $QUANTITY$ nhiều hơn", "placeholders": { "quantity": { "content": "$1", @@ -2895,136 +2973,168 @@ } }, "submenu": { - "message": "Submenu" + "message": "Menu con" }, "toggleCollapse": { - "message": "Toggle collapse", + "message": "Bật/tắt thu gọn", "description": "Toggling an expand/collapse state." }, "filelessImport": { - "message": "Import your data to Bitwarden?", + "message": "Nhập dữ liệu của bạn vào Bitwarden?", "description": "Default notification title for triggering a fileless import." }, "lpFilelessImport": { - "message": "Protect your LastPass data and import to Bitwarden?", + "message": "Bảo vệ dữ liệu LastPass của bạn và nhập vào Bitwarden?", "description": "LastPass specific notification title for triggering a fileless import." }, "lpCancelFilelessImport": { - "message": "Save as unencrypted file", + "message": "Lưu dưới dạng tập tin không được mã hóa", "description": "LastPass specific notification button text for cancelling a fileless import." }, "startFilelessImport": { - "message": "Import to Bitwarden", + "message": "Nhập vào Bitwarden", "description": "Notification button text for starting a fileless import." }, "importing": { - "message": "Importing...", + "message": "Đang nhập...", "description": "Notification message for when an import is in progress." }, "dataSuccessfullyImported": { - "message": "Data successfully imported!", + "message": "Dữ liệu đã được nhập thành công!", "description": "Notification message for when an import has completed successfully." }, "dataImportFailed": { - "message": "Error importing. Check console for details.", + "message": "Xảy ra lỗi trong quá trình nhập. Kiểm tra bảng điều khiển để biết thêm chi tiết.", "description": "Notification message for when an import has failed." }, "importNetworkError": { - "message": "Network error encountered during import.", + "message": "Đã xảy ra lỗi mạng trong quá trình nhập dữ liệu.", "description": "Notification message for when an import has failed due to a network error." }, "aliasDomain": { - "message": "Alias domain" + "message": "Tên miền thay thế" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Items with master password re-prompt cannot be auto-filled on page load. Auto-fill on page load turned off.", + "message": "Các mục yêu cầu nhập lại mật khẩu chính không thể tự động điền khi tải trang. Tự động điền khi tải trang đã tắt.", "description": "Toast message for describing that master password re-prompt cannot be auto-filled on page load." }, "autofillOnPageLoadSetToDefault": { - "message": "Auto-fill on page load set to use default setting.", + "message": "Tự động điền khi tải trang được đặt thành mặc định trong cài đặt.", "description": "Toast message for informing the user that auto-fill on page load has been set to the default setting." }, "turnOffMasterPasswordPromptToEditField": { - "message": "Turn off master password re-prompt to edit this field", + "message": "Tắt yêu cầu nhập lại mật khẩu chính để chỉnh sửa trường này", "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Ẩn/hiện thanh điều hướng bên" }, "skipToContent": { - "message": "Skip to content" + "message": "Chuyển đến nội dung" }, "bitwardenOverlayButton": { - "message": "Bitwarden auto-fill menu button", + "message": "Nút menu tự động điền Bitwarden", "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Toggle Bitwarden auto-fill menu", + "message": "Bật/tắt menu tự động điền Bitwarden", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden auto-fill menu", + "message": "Menu tự động điền Bitwarden", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "Mở khóa tài khoản của bạn để xem các thông tin đăng nhập phù hợp", + "description": "Text to display in overlay when the account is locked." + }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "Mở khóa tài khoản", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { - "message": "Fill credentials for", + "message": "Điền thông tin đăng nhập cho", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { - "message": "Partial username", + "message": "Tên người dùng từng phần", "description": "Screen reader text for when a login item is focused where a partial username is displayed. SR will announce this phrase before reading the text of the partial username" }, "noItemsToShow": { - "message": "No items to show", + "message": "Không có mục nào để hiển thị", "description": "Text to show in overlay if there are no matching items" }, "newItem": { - "message": "New item", + "message": "Mục mới", "description": "Button text to display in overlay when there are no matching items" }, "addNewVaultItem": { - "message": "Add new vault item", + "message": "Thêm mục mới", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { - "message": "Bitwarden auto-fill menu available. Press the down arrow key to select.", + "message": "Danh sách tự động điền của Bitwarden sẵn sàng. Sử dụng phím mũi tên xuống để chọn.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { - "message": "Turn on" + "message": "Bật" }, "ignore": { - "message": "Ignore" + "message": "Bỏ qua" }, "importData": { - "message": "Import data", + "message": "Nhập dữ liệu", "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" }, "importError": { - "message": "Import error" + "message": "Lỗi nhập" }, "importErrorDesc": { - "message": "There was a problem with the data you tried to import. Please resolve the errors listed below in your source file and try again." + "message": "Có vấn đề với dữ liệu bạn cố gắng nhập. Vui lòng khắc phục các lỗi được liệt kê bên dưới trong tệp nguồn của bạn và thử lại." }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "Giải quyết các lỗi bên dưới và thử lại." }, "description": { - "message": "Description" + "message": "Mô tả" }, "importSuccess": { - "message": "Data successfully imported" + "message": "Dữ liệu đã được nhập thành công" }, "importSuccessNumberOfItems": { - "message": "A total of $AMOUNT$ items were imported.", + "message": "Đã nhập tổng cộng $AMOUNT$ mục.", "placeholders": { "amount": { "content": "$1", @@ -3033,46 +3143,46 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Thử lại" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Cần xác minh cho thao tác này. Hãy đặt mã PIN để tiếp tục." }, "setPin": { - "message": "Set PIN" + "message": "Thiết lập mã PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Xác thực bằng sinh trắc học" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Đang chờ xác nhận" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Không thể hoàn tất sinh trắc học." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Cần một phương pháp khác?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Dùng mật khẩu chính" }, "usePin": { - "message": "Use PIN" + "message": "Dùng mã PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Dùng sinh trắc học" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "Nhập mã xác minh được gửi đến email của bạn." }, "resendCode": { - "message": "Resend code" + "message": "Gửi lại mã" }, "total": { - "message": "Total" + "message": "Tổng" }, "importWarning": { - "message": "You are importing data to $ORGANIZATION$. Your data may be shared with members of this organization. Do you want to proceed?", + "message": "Bạn đang nhập dữ liệu vào $ORGANIZATION$. Dữ liệu của bạn có thể được chia sẻ với các thành viên của tổ chức này. Bạn có muốn tiếp tục không?", "placeholders": { "organization": { "content": "$1", @@ -3081,49 +3191,49 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Lỗi kết nối với dịch vụ Duo. Sử dụng phương thức đăng nhập hai bước khác hoặc liên hệ với Duo để được hỗ trợ." }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Khởi chạy Duo và làm theo các bước để hoàn tất đăng nhập." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Tài khoản của bạn yêu cầu xác minh hai bước với Duo." }, "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." + "message": "Bật tiện ích mở rộng để hoàn tất đăng nhập." }, "popoutExtension": { - "message": "Popout extension" + "message": "Tiện ích mở rộng dạng cửa sổ bật lên" }, "launchDuo": { - "message": "Launch Duo" + "message": "Khởi chạy Dou" }, "importFormatError": { - "message": "Data is not formatted correctly. Please check your import file and try again." + "message": "Dữ liệu không được định dạng đúng. Vui lòng kiểm tra tập tin nhập và thử lại." }, "importNothingError": { - "message": "Nothing was imported." + "message": "Không có gì được nhập." }, "importEncKeyError": { - "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." + "message": "Lỗi giải mã tập tin đã xuất. Khóa mã hóa của bạn không khớp với khóa mã hóa được sử dụng để xuất dữ liệu." }, "invalidFilePassword": { - "message": "Invalid file password, please use the password you entered when you created the export file." + "message": "Mật khẩu tập tin không hợp lệ, vui lòng sử dụng mật khẩu bạn đã nhập khi xuất tập tin." }, - "importDestination": { - "message": "Import destination" + "destination": { + "message": "Đến" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "Tìm hiểu các tuỳ chọn nhập của bạn" }, "selectImportFolder": { - "message": "Select a folder" + "message": "Chọn thư mục" }, "selectImportCollection": { - "message": "Select a collection" + "message": "Chọn bộ sưu tập" }, "importTargetHint": { - "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", + "message": "Chọn tùy chọn này để di chuyển nội dung tập tin đã được nhập đến $DESTINATION$", "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": { @@ -3133,25 +3243,25 @@ } }, "importUnassignedItemsError": { - "message": "File contains unassigned items." + "message": "Tập tin chứa các mục không xác định." }, "selectFormat": { - "message": "Select the format of the import file" + "message": "Chọn định dạng tập tin nhập" }, "selectImportFile": { - "message": "Select the import file" + "message": "Chọn tập tin nhập" }, "chooseFile": { - "message": "Choose File" + "message": "Chọn tập tin" }, "noFileChosen": { - "message": "No file chosen" + "message": "Chưa chọn tập tin nào" }, "orCopyPasteFileContents": { - "message": "or copy/paste the import file contents" + "message": "hoặc sao chép/dán để nhập nội dung file" }, "instructionsFor": { - "message": "$NAME$ Instructions", + "message": "Hướng dẫn dùng $NAME$", "description": "The title for the import tool instructions.", "placeholders": { "name": { @@ -3161,258 +3271,282 @@ } }, "confirmVaultImport": { - "message": "Confirm vault import" + "message": "Xác nhận nhập kho" }, "confirmVaultImportDesc": { - "message": "This file is password-protected. Please enter the file password to import data." + "message": "Tập tin này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu để nhập dữ liệu." }, "confirmFilePassword": { - "message": "Confirm file password" + "message": "Nhập lại mật khẩu tập tin" }, "exportSuccess": { - "message": "Vault data exported" + "message": "Đã xuất dữ liệu kho của bạn" }, "typePasskey": { - "message": "Passkey" + "message": "Mã khoá" }, "passkeyNotCopied": { - "message": "Passkey will not be copied" + "message": "Không thể sao chép mã khoá" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "Bản sao sẽ không bao gồm mã khoá. Bạn có muốn tiếp tục tạo bản sao mục này?" }, "passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": { - "message": "Verification required by the initiating site. This feature is not yet implemented for accounts without master password." + "message": "Trang web yêu cầu xác minh. Tính năng này hiện chưa được hỗ trợ cho tài khoản không có mật khẩu chính." }, "logInWithPasskey": { - "message": "Log in with passkey?" + "message": "Đăng nhập bằng mã khoá?" }, "passkeyAlreadyExists": { - "message": "A passkey already exists for this application." + "message": "Ứng dụng này đã có mã khoá." }, "noPasskeysFoundForThisApplication": { - "message": "No passkeys found for this application." + "message": "Không có mã khoá cho ứng dụng này." }, "noMatchingPasskeyLogin": { - "message": "You do not have a matching login for this site." + "message": "Bạn không có thông tin đăng nhập phù hợp cho trang web này." }, "confirm": { - "message": "Confirm" + "message": "Xác nhận" }, "savePasskey": { - "message": "Save passkey" + "message": "Lưu mã khoá" }, "savePasskeyNewLogin": { - "message": "Save passkey as new login" + "message": "Lưu mã khoá như đăng nhập mới" }, "choosePasskey": { - "message": "Choose a login to save this passkey to" + "message": "Chọn thông tin đăng nhập để lưu mã khoá này vào" }, "passkeyItem": { - "message": "Passkey Item" + "message": "Mục mã khoá" }, "overwritePasskey": { - "message": "Overwrite passkey?" + "message": "Ghi đè mã khoá?" }, "overwritePasskeyAlert": { - "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + "message": "Mục này đã chứa mã khoá. Bạn có chắc muốn ghi đè mã khoá hiện tại không?" }, "featureNotSupported": { - "message": "Feature not yet supported" + "message": "Chưa hỗ trợ tính năng này" }, "yourPasskeyIsLocked": { - "message": "Authentication required to use passkey. Verify your identity to continue." + "message": "Yêu cầu xác thực để sử dụng mã khoá. Xác minh danh tính của bạn để tiếp tục." }, "multifactorAuthenticationCancelled": { - "message": "Multifactor authentication cancelled" + "message": "Đã hủy xác thực đa yếu tố" }, "noLastPassDataFound": { - "message": "No LastPass data found" + "message": "Không tìm thấy dữ liệu LastPass" }, "incorrectUsernameOrPassword": { - "message": "Incorrect username or password" + "message": "Tên người dùng hoặc mật khẩu không đúng" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Mật khẩu không đúng" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Mã không đúng" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "Mã PIN không đúng" }, "multifactorAuthenticationFailed": { - "message": "Multifactor authentication failed" + "message": "Xác thực đa yếu tố thất bại" }, "includeSharedFolders": { - "message": "Include shared folders" + "message": "Bao gồm các thư mục được chia sẻ" }, "lastPassEmail": { - "message": "LastPass Email" + "message": "Email LastPass" }, "importingYourAccount": { - "message": "Importing your account..." + "message": "Đang nhập tài khoản của bạn..." }, "lastPassMFARequired": { - "message": "LastPass multifactor authentication required" + "message": "Yêu cầu xác thực đa yếu tố LastPass" }, "lastPassMFADesc": { - "message": "Enter your one-time passcode from your authentication app" + "message": "Nhập mã OTP từ ứng dụng xác thực của bạn" }, "lastPassOOBDesc": { - "message": "Approve the login request in your authentication app or enter a one-time passcode." + "message": "Phê duyệt yêu cầu đăng nhập trên ứng dụng xác thực của bạn hoặc nhập mã OTP." }, "passcode": { - "message": "Passcode" + "message": "Mật mã" }, "lastPassMasterPassword": { - "message": "LastPass master password" + "message": "Mật khẩu chính LastPass" }, "lastPassAuthRequired": { - "message": "LastPass authentication required" + "message": "Yêu cầu xác thực LastPass" }, "awaitingSSO": { - "message": "Awaiting SSO authentication" + "message": "Đang chờ xác thực SSO" }, "awaitingSSODesc": { - "message": "Please continue to log in using your company credentials." + "message": "Vui lòng tiếp tục đăng nhập bằng thông tin đăng nhập của công ty bạn." }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "Xem hướng dẫn chi tiết trên trang trợ giúp của chúng tôi tại", "description": "This is followed a by a hyperlink to the help website." }, "importDirectlyFromLastPass": { - "message": "Import directly from LastPass" + "message": "Nhập trực tiếp từ LastPass" }, "importFromCSV": { - "message": "Import from CSV" + "message": "Nhập từ CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Try again or look for an email from LastPass to verify it's you." + "message": "Thử lại hoặc tìm email từ LastPass để xác minh đó là bạn." }, "collection": { - "message": "Collection" + "message": "Bộ Sưu Tập" }, "lastPassYubikeyDesc": { - "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." + "message": "Cắm khóa YubiKey được liên kết với tài khoản LastPass của bạn vào cổng USB của máy tính, sau đó nhấn nút trên YubiKey." }, "switchAccount": { - "message": "Switch account" + "message": "Chuyển tài khoản" }, "switchAccounts": { - "message": "Switch accounts" + "message": "Chuyển đổi tài khoản" }, "switchToAccount": { - "message": "Switch to account" + "message": "Chuyển sang tài khoản" }, "activeAccount": { - "message": "Active account" + "message": "Tài khoản đang hoạt động" }, "availableAccounts": { - "message": "Available accounts" + "message": "Các tài khoản khả dụng" }, "accountLimitReached": { - "message": "Account limit reached. Log out of an account to add another." + "message": "Số lượng tài khoản đã đạt giới hạn. Đăng xuất khỏi một tài khoản để thêm tài khoản khác." }, "active": { - "message": "active" + "message": "hoạt động" }, "locked": { - "message": "locked" + "message": "đã khóa" }, "unlocked": { - "message": "unlocked" + "message": "đã mở khóa" }, "server": { - "message": "server" + "message": "máy chủ" }, "hostedAt": { - "message": "hosted at" + "message": "được lưu trữ tại" }, "useDeviceOrHardwareKey": { - "message": "Use your device or hardware key" + "message": "Sử dụng thiết bị hoặc khóa phần cứng của bạn" }, "justOnce": { - "message": "Just once" + "message": "Chỉ một lần" }, "alwaysForThisSite": { - "message": "Always for this site" + "message": "Luôn cho trang này" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ added to excluded domains.", + "message": "$DOMAIN$ đã được thêm vào danh sách các tên miền loại trừ.", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, "commonImportFormats": { - "message": "Common formats", + "message": "Định dạng chung", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Tiếp tục tới Cài đặt trình duyệt?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Đi đến Trung tâm trợ giúp?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Thay đổi cài đặt tự động điền và quản lý mật khẩu của trình duyệt của bạn.", + "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": "Bạn có thể xem và đặt các phím tắt của tiện ích mở rộng trong phần cài đặt trình duyệt.", + "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": "Thay đổi cài đặt tự động điền và quản lý mật khẩu của trình duyệt của bạn.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "Bạn có thể xem và thiết lập các phím tắt của tiện ích mở rộng trong phần cài đặt trình duyệt.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { - "message": "Make Bitwarden your default password manager?", + "message": "Đặt Bitwarden làm trình quản lý mật khẩu mặc định của bạn?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Bỏ qua tùy chọn này có thể gây ra xung đột giữa các đề xuất tự động điền của Bitwarden và trình duyệt của bạn.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { - "message": "Make Bitwarden your default password manager", + "message": "Đặt Bitwarden làm trình quản lý mật khẩu mặc định của bạn", "description": "Label for the setting that allows overriding the default browser autofill settings" }, "privacyPermissionAdditionNotGrantedTitle": { - "message": "Unable to set Bitwarden as the default password manager", + "message": "Không thể đặt Bitwarden làm trình quản lý mật khẩu mặc định", "description": "Title for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "privacyPermissionAdditionNotGrantedDescription": { - "message": "You must grant browser privacy permissions to Bitwarden to set it as the default password manager.", + "message": "Bạn phải cấp quyền riêng tư của trình duyệt cho Bitwarden để đặt nó làm trình quản lý mật khẩu mặc định.", "description": "Description for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "makeDefault": { - "message": "Make default", + "message": "Đặt làm mặc định", "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "Thông tin đăng nhập đã lưu thành công!", "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "Thông tin đăng nhập đã được cập nhật thành công!", "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "Xảy ra lỗi trong quá trình lưu thông tin đăng nhập. Kiểm tra bảng điều khiển để biết thêm chi tiết.", "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "Thành công" }, "removePasskey": { - "message": "Remove passkey" + "message": "Xóa mã khoá" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Đã xóa mã khoá" }, "autofillSuggestions": { - "message": "Auto-fill suggestions" + "message": "Gợi ý điền tự động" }, "autofillSuggestionsTip": { - "message": "Save a login item for this site to auto-fill" + "message": "Lưu thông tin đăng nhập cho trang này để tự động điền" }, "yourVaultIsEmpty": { - "message": "Your vault is empty" + "message": "Kho của bạn trống" }, "noItemsMatchSearch": { - "message": "No items match your search" + "message": "Không có kết quả nào phù hợp với tìm kiếm của bạn" }, "clearFiltersOrTryAnother": { - "message": "Clear filters or try another search term" + "message": "Xóa bộ lọc hoặc thử từ khóa tìm kiếm khác" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Sao chép thông tin - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -3422,7 +3556,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Sao chép ghi chú - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -3432,7 +3566,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Thêm tùy chọn, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3442,7 +3576,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Thêm tùy chọn - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3452,7 +3586,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Xem mục - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -3462,7 +3596,7 @@ } }, "autofillTitle": { - "message": "Auto-fill - $ITEMNAME$", + "message": "Tự động điền - $ITEMNAME$", "description": "Title for a button that auto-fills a login item.", "placeholders": { "itemname": { @@ -3472,40 +3606,40 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "Không có giá trị để sao chép" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Gán vào bộ sưu tập" }, "copyEmail": { - "message": "Copy email" + "message": "Sao chép email" }, "copyPhone": { - "message": "Copy phone" + "message": "Sao chép số điện thoại" }, "copyAddress": { - "message": "Copy address" + "message": "Sao chép địa chỉ" }, "adminConsole": { "message": "Bảng điều khiển dành cho quản trị viên" }, "accountSecurity": { - "message": "Account security" + "message": "Bảo mật tài khoản" }, "notifications": { - "message": "Notifications" + "message": "Thông báo" }, "appearance": { - "message": "Appearance" + "message": "Giao diện" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Lỗi khi gán vào bộ sưu tập chỉ định." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Lỗi khi gán vào thư mục chỉ định." }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Xem các mục trong $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -3515,7 +3649,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Quay lại $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -3525,10 +3659,10 @@ } }, "new": { - "message": "New" + "message": "Mới" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Xoá $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -3538,16 +3672,16 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "Các mục không được phân loại" }, "itemDetails": { - "message": "Item details" + "message": "Chi tiết mục" }, "itemName": { - "message": "Item name" + "message": "Tên mục" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "Bạn không thể xóa các bộ sưu tập với quyền chỉ xem: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -3556,47 +3690,47 @@ } }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "Tổ chức không còn hoạt động" }, "owner": { - "message": "Owner" + "message": "Chủ sở hữu" }, "selfOwnershipLabel": { - "message": "You", + "message": "Bạn", "description": "Used as a label to indicate that the user is the owner of an item." }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "Không thể truy cập các mục trong tổ chức đã ngưng hoạt động. Hãy liên hệ với chủ sở hữu tổ chức để được hỗ trợ." }, "additionalInformation": { - "message": "Additional information" + "message": "Thông tin bổ sung" }, "itemHistory": { - "message": "Item history" + "message": "Lịch sử mục" }, "lastEdited": { - "message": "Last edited" + "message": "Chỉnh sửa lần cuối" }, "ownerYou": { - "message": "Owner: You" + "message": "Chủ sở hữu: Bạn" }, "linked": { - "message": "Linked" + "message": "Đã liên kết" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Sao chép thành công" }, "upload": { - "message": "Upload" + "message": "Tải lên" }, "addAttachment": { - "message": "Add attachment" + "message": "Thêm tệp đính kèm" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "Kích thước tối đa của tệp tin là 500MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "Xoá tệp đính kèm $NAME$", "placeholders": { "name": { "content": "$1", @@ -3605,7 +3739,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "Tải xuống $NAME$", "placeholders": { "name": { "content": "$1", @@ -3614,28 +3748,28 @@ } }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "Bạn có chắc chắn muốn xóa vĩnh viễn tệp đính kèm này không?" }, "premium": { - "message": "Premium" + "message": "Cao cấp" }, "freeOrgsCannotUseAttachments": { - "message": "Free organizations cannot use attachments" + "message": "Các tổ chức miễn phí không thể sử dụng tệp đính kèm" }, "filters": { - "message": "Filters" + "message": "Bộ lọc" }, "personalDetails": { - "message": "Personal details" + "message": "Thông tin cá nhân" }, "identification": { - "message": "Identification" + "message": "ID" }, "contactInfo": { - "message": "Contact info" + "message": "Thông tin liên hệ" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "Tải xuống - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -3643,17 +3777,21 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "Thông tin đăng nhập" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Khóa xác thực" }, "cardDetails": { - "message": "Card details" + "message": "Thông tin thẻ" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "Chi tiết $BRAND$", "placeholders": { "brand": { "content": "$1", @@ -3662,19 +3800,25 @@ } }, "addAccount": { - "message": "Add account" + "message": "Thêm tài khoản" }, "loading": { - "message": "Loading" + "message": "Đang tải" + }, + "data": { + "message": "Dữ liệu" }, "assign": { - "message": "Assign" + "message": "Gán" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Chỉ những thành viên của tổ chức có quyền truy cập vào các bộ sưu tập này mới có thể xem mục này." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "Chỉ những thành viên của tổ chức có quyền truy cập vào các bộ sưu tập này mới có thể xem các mục này." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Bạn đã chọn $TOTAL_COUNT$ mục. Bạn không thể cập nhật $READONLY_COUNT$ mục vì bạn không có quyền chỉnh sửa.", "placeholders": { "total_count": { "content": "$1", @@ -3686,37 +3830,37 @@ } }, "addField": { - "message": "Add field" + "message": "Thêm trường" }, "add": { - "message": "Add" + "message": "Thêm" }, "fieldType": { - "message": "Field type" + "message": "Loại trường" }, "fieldLabel": { - "message": "Field label" + "message": "Tiêu đề trường" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Sử dụng các trường nhập liệu văn bản cho dữ liệu như câu hỏi bảo mật" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Sử dụng các trường nhập liệu ẩn cho thông tin nhạy cảm như mật khẩu" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to auto-fill a form's checkbox, like a remember email" + "message": "Dùng các ô tích chọn nếu bạn muốn tự động điền vào ô tích chọn của biểu mẫu, chẳng hạn như ghi nhớ email" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing auto-fill issues for a specific website." + "message": "Sử dụng trường nhập liệu đã liên kết khi bạn gặp vấn đề với việc tự động điền trên một trang web cụ thể." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "Nhập thông tin định danh của trường như id, name, aria-label hoặc placeholder." }, "editField": { - "message": "Edit field" + "message": "Chỉnh sửa trường" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "Chỉnh sửa $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3725,7 +3869,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "Xoá $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3734,7 +3878,7 @@ } }, "fieldAdded": { - "message": "$LABEL$ added", + "message": "Đã thêm $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3743,7 +3887,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "Sắp xếp lại $LABEL$. Sử dụng phím mũi tên để di chuyển mục lên hoặc xuống.", "placeholders": { "label": { "content": "$1", @@ -3752,7 +3896,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ đã di chuyển lên vị trí $INDEX$ / $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3769,23 +3913,35 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Chọn bộ sưu tập để gán" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 mục sẽ được chuyển vĩnh viễn đến tổ chức đã chọn. Bạn sẽ không còn sở hữu mục này nữa." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ mục sẽ được chuyển vĩnh viễn đến tổ chức đã chọn. Bạn sẽ không còn sở hữu các mục này nữa.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 mục sẽ được chuyển vĩnh viễn đến $ORG$. Bạn sẽ không còn sở hữu mục này nữa.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ mục sẽ được chuyển vĩnh viễn đến $ORG$. Bạn sẽ không còn sở hữu các mục này nữa.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3794,13 +3950,31 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Đã gán vào bộ sưu tập thành công" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Bạn chưa chọn gì." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Đã chuyển các mục được chọn đến $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemsMovedToOrg": { + "message": "Các mục đã được chuyển tới $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Mục đã được chuyển tới $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3809,7 +3983,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ đã di chuyển xuống vị trí $INDEX$ / $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Vị trí mục" } } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 28f6419afa9..4f649589d0f 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "登录或者创建一个账户来访问您的安全密码库。" }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "创建账户" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "主密码提示(可选)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "标签页" }, @@ -640,13 +649,13 @@ "message": "从当前网页扫描验证器二维码" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "无缝两步验证" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden 可以存储并填充两步验证码。复制并粘贴密钥到此字段。" }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden 可以存储并填充两步验证码。选择相机图标来截取此网站的验证器二维码,或者手动复制并粘贴密钥到此字段。" }, "copyTOTP": { "message": "复制验证器密钥 (TOTP)" @@ -661,19 +670,19 @@ "message": "您的登录会话已过期。" }, "logIn": { - "message": "Log in" + "message": "登录" }, "restartRegistration": { - "message": "Restart registration" + "message": "重新开始注册" }, "expiredLink": { - "message": "Expired link" + "message": "失效链接" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "请重新注册或尝试登录。" }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "您可能已经有一个账户了" }, "logOutConfirmation": { "message": "确定要注销吗?" @@ -736,6 +745,10 @@ "newUri": { "message": "新增 URI" }, + "addDomain": { + "message": "添加域名", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "项目已添加" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "询问添加登录" }, + "vaultSaveOptionsTitle": { + "message": "保存到密码库选项" + }, "addLoginNotificationDesc": { "message": "在密码库中找不到匹配项目时询问添加一个。" }, "addLoginNotificationDescAlt": { "message": "如果在密码库中找不到项目,询问添加一个。适用于所有已登录的账户。" }, + "showCardsInVaultView": { + "message": "在密码库视图中将支付卡显示为自动填充建议" + }, "showCardsCurrentTab": { "message": "在标签页上显示支付卡" }, "showCardsCurrentTabDesc": { "message": "在标签页上列出支付卡项目,以便于自动填充。" }, + "showIdentitiesInVaultView": { + "message": "在密码库视图中将支身份显示为自动填充建议" + }, "showIdentitiesCurrentTab": { "message": "在标签页上显示身份" }, @@ -1220,11 +1242,20 @@ "message": "在表单字段上显示自动填充菜单", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { + "autofillSuggestionsSectionTitle": { + "message": "自动填充建议" + }, + "showInlineMenuLabel": { + "message": "在表单字段中显示自动填充建议" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "选择图标时显示建议" + }, + "showInlineMenuOnFormFieldsDescAlt": { "message": "适用于所有已登录的账户。" }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "关闭您浏览器自带的密码管理器设置以避免冲突。" + "message": "关闭您浏览器内置的密码管理器设置以避免冲突。" }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "编辑浏览器设置。" @@ -1241,14 +1272,33 @@ "message": "选中自动填充图标时", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "页面加载时自动填充" + }, "enableAutoFillOnPageLoad": { "message": "页面加载时自动填充" }, "enableAutoFillOnPageLoadDesc": { - "message": "网页加载时如果检测到登录表单,则执行自动填充。" + "message": "如果检测到登录表单,则在网页加载时执行自动填充。" + }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$警告:$CLOSETAG$不完整或不信任的网站可以利用页面加载时的自动填充功能。", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } }, "experimentalFeature": { - "message": "不完整或不信任的网站可以在页面加载时自动填充。" + "message": "不完整或不信任的网站可以利用页面加载时的自动填充功能。" + }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "了解更多关于风险的信息" }, "learnMoreAboutAutofill": { "message": "了解更多关于自动填充的信息" @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "布尔型" }, + "cfTypeCheckbox": { + "message": "复选框型" + }, "cfTypeLinked": { "message": "链接型", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1848,7 +1901,7 @@ "message": "您的新主密码不符合策略要求。" }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "获取来自 Bitwarden 的建议、公告和调研电子邮件。" }, "unsubscribe": { "message": "取消订阅" @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "组织策略已阻止将项目导入您的个人密码库。" }, + "domainsTitle": { + "message": "域名", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "排除域名" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "Bitwarden 不会询问保存所有已登录的账户的这些域名的登录信息。必须刷新页面才能使更改生效。" }, + "websiteItemLabel": { + "message": "网站 $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ 不是一个有效的域名", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "排除域名更改已保存" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "密码保护" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "复制 Send 链接", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "自动填充设置" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "自动填充快捷键" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "更改快捷键" + }, "autofillShortcut": { "message": "自动填充键盘快捷键" }, @@ -2696,7 +2774,7 @@ } }, "autofillShortcutTextSafari": { - "message": "默认自动填充快捷方式:$COMMAND$。", + "message": "默认自动填充快捷键:$COMMAND$", "placeholders": { "command": { "content": "$1", @@ -2732,7 +2810,7 @@ "message": "必须填写组织 SSO 标识符。" }, "creatingAccountOn": { - "message": "创建账户于" + "message": "正创建账户于" }, "checkYourEmail": { "message": "检查您的电子邮箱" @@ -2970,10 +3048,18 @@ "message": "解锁您的账户以查看匹配的登录", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "解锁账户", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "为其填写凭据", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "添加新的密码库项目", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden 自动填充菜单可用。按向下箭头键进行选择。", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "无效的文件密码,请使用您创建导出文件时输入的密码。" }, - "importDestination": { - "message": "导入目的地" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "了解您的导入选项" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "常规格式", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "前往浏览器设置吗?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "前往帮助中心吗?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "更改浏览器的自动填充和密码管理设置。", + "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": "您可以在浏览器的设置中查看和设置扩展的快捷键。", + "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": "更改浏览器的自动填充和密码管理设置。", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "您可以在浏览器的设置中查看和设置扩展的快捷键。", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "将 Bitwarden 设置为您的默认密码管理器吗?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "忽略此选项可能会导致 Bitwarden 自动填充菜单与浏览器自带功能产生冲突。", + "message": "忽略此选项可能会导致 Bitwarden 自动填充建议与浏览器产生冲突。", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "没有要复制的值" }, - "assignCollections": { - "message": "分配集合" + "assignToCollections": { + "message": "分配到集合" }, "copyEmail": { "message": "复制电子邮件地址" @@ -3643,11 +3777,15 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { - "message": "Login credentials" + "message": "登录凭据" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "验证器密钥" }, "cardDetails": { "message": "支付卡详情" @@ -3667,14 +3805,20 @@ "loading": { "message": "加载中" }, - "assign": { - "message": "Assign" + "data": { + "message": "Data" }, - "bulkCollectionAssignmentDialogDescription": { - "message": "Only organization members with access to these collections will be able to see the items." + "assign": { + "message": "分配" + }, + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "只有具有这些集合访问权限的组织成员才能看到这个项目。" + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { + "message": "只有具有这些集合访问权限的组织成员才能看到这些项目。" }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "您选择了 $TOTAL_COUNT$ 个项目。其中的 $READONLY_COUNT$ 个项目由于您没有编辑权限,您将无法更新它们。", "placeholders": { "total_count": { "content": "$1", @@ -3698,13 +3842,13 @@ "message": "字段标签" }, "textHelpText": { - "message": "文本型字段用于比如安全问题之类的数据" + "message": "对于如安全问题之类的数据,请使用文本型字段" }, "hiddenHelpText": { - "message": "隐藏型字段用于比如密码之类的敏感数据" + "message": "对于如密码之类的敏感数据,请使用隐藏型字段" }, "checkBoxHelpText": { - "message": "如果您想自动勾选表单复选框(例如记住电子邮件地址),请勾选复选框" + "message": "如果您想自动勾选表单复选框(例如记住电子邮件地址),请使用复选框" }, "linkedHelpText": { "message": "当您处理特定网站的自动填充问题时,请使用链接型字段。" @@ -3769,23 +3913,35 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "选择要分配的集合" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 个项目将永久转移到所选组织。您将不再拥有该项目。" + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 个项目将永久转移到所选组织。您将不再拥有这些项目。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 个项目将永久转移到 $ORG$ 。您将不再拥有该项目。", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ 个项目将永久转移到 $ORG$ 。您将不再拥有这些项目。", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3794,13 +3950,31 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "成功分配了集合" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "您尚未选择任何内容。" }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "所选项目已移动到 $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemsMovedToOrg": { + "message": "项目已移动到 $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "项目已移动到 $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "项目位置" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index c5ac6a6d52e..fe9ae47ada3 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "登入或建立帳戶以存取您的安全密碼庫。" }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "建立帳戶" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "主密碼提示(選用)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "分頁" }, @@ -108,7 +117,7 @@ "message": "複製安全代碼" }, "autoFill": { - "message": "自動填入" + "message": "自動填寫" }, "autoFillLogin": { "message": "自動填入登入資訊" @@ -736,6 +745,10 @@ "newUri": { "message": "新增 URI" }, + "addDomain": { + "message": "Add domain", + "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." + }, "addedItem": { "message": "項目已新增" }, @@ -776,18 +789,27 @@ "enableAddLoginNotification": { "message": "詢問新增登入資料" }, + "vaultSaveOptionsTitle": { + "message": "Save to vault options" + }, "addLoginNotificationDesc": { "message": "在密碼庫中找不到相符的項目時詢問是否新增項目。" }, "addLoginNotificationDescAlt": { "message": "如果在您的密碼庫中找不到項目,則詢問是否新增項目。適用於所有已登入的帳戶。" }, + "showCardsInVaultView": { + "message": "Show cards as Autofill suggestions on Vault view" + }, "showCardsCurrentTab": { "message": "於分頁頁面顯示支付卡" }, "showCardsCurrentTabDesc": { "message": "於分頁頁面顯示支付卡以便於自動填入。" }, + "showIdentitiesInVaultView": { + "message": "Show identifies as Autofill suggestions on Vault view" + }, "showIdentitiesCurrentTab": { "message": "於分頁頁面顯示身分" }, @@ -1220,8 +1242,17 @@ "message": "在表單欄位上顯示自動填入選單", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, - "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "適用於所有已登入的帳戶。" + "autofillSuggestionsSectionTitle": { + "message": "Autofill suggestions" + }, + "showInlineMenuLabel": { + "message": "Show autofill suggestions on form fields" + }, + "showInlineMenuOnIconSelectionLabel": { + "message": "Display suggestions when icon is selected" + }, + "showInlineMenuOnFormFieldsDescAlt": { + "message": "Applies to all logged in accounts." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "關閉你的瀏覽器內建密碼管理器設定以避免衝突。" @@ -1241,15 +1272,34 @@ "message": "當選取自動填入圖示時", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, + "enableAutoFillOnPageLoadSectionTitle": { + "message": "Autofill on page load" + }, "enableAutoFillOnPageLoad": { "message": "頁面載入時自動填入" }, "enableAutoFillOnPageLoadDesc": { "message": "網頁載入時如果偵測到登入表單,則執行自動填入。" }, + "autofillOnPageLoadWarning": { + "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "placeholders": { + "openTag": { + "content": "$1", + "example": "" + }, + "closeTag": { + "content": "$2", + "example": "" + } + } + }, "experimentalFeature": { "message": "被入侵或不可信任的網站可不當利用頁面載入時的自動填入功能。" }, + "learnMoreAboutAutofillOnPageLoadLinkText": { + "message": "Learn more about risks" + }, "learnMoreAboutAutofill": { "message": "進一步瞭解「自動填入」功能" }, @@ -1310,6 +1360,9 @@ "cfTypeBoolean": { "message": "布林值" }, + "cfTypeCheckbox": { + "message": "Checkbox" + }, "cfTypeLinked": { "message": "連結型", "description": "This describes a field that is 'linked' (tied) to another field." @@ -1967,6 +2020,10 @@ "personalOwnershipPolicyInEffectImports": { "message": "某個組織原則已禁止您將項目匯入至您的個人密碼庫。" }, + "domainsTitle": { + "message": "Domains", + "description": "A category title describing the concept of web domains" + }, "excludedDomains": { "message": "排除網域" }, @@ -1976,15 +2033,27 @@ "excludedDomainsDescAlt": { "message": "對於所有已登入的帳戶,Bitwarden 不會詢問是否儲存這些網域的登入資訊。您必須重新整理頁面以使變更生效。" }, + "websiteItemLabel": { + "message": "Website $number$ (URI)", + "placeholders": { + "number": { + "content": "$1", + "example": "3" + } + } + }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ 不是一個有效的網域", "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, + "excludedDomainsSavedSuccess": { + "message": "Excluded domain changes saved" + }, "send": { "message": "Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2020,6 +2089,9 @@ "passwordProtected": { "message": "密碼保護" }, + "copyLink": { + "message": "Copy link" + }, "copySendLink": { "message": "複製 Send 連結", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2680,6 +2752,12 @@ "autofillSettings": { "message": "自動填入設定" }, + "autofillKeyboardShortcutSectionTitle": { + "message": "Autofill shortcut" + }, + "autofillKeyboardShortcutUpdateLabel": { + "message": "Change shortcut" + }, "autofillShortcut": { "message": "自動填入鍵盤快速鍵" }, @@ -2687,7 +2765,7 @@ "message": "自動填入快速鍵尚未設定。請在瀏覽器的設定中變更。" }, "autofillShortcutText": { - "message": "自動填入快速鍵:$COMMAND$。請在瀏覽器的設定中變更。", + "message": "自動填入快速鍵:$COMMAND$。可在瀏覽器的設定中變更。", "placeholders": { "command": { "content": "$1", @@ -2970,10 +3048,18 @@ "message": "解鎖您的帳戶以查看符合的登入資訊", "description": "Text to display in overlay when the account is locked." }, + "unlockYourAccountToViewAutofillSuggestions": { + "message": "Unlock your account to view autofill suggestions", + "description": "Text to display in overlay when the account is locked." + }, "unlockAccount": { "message": "解鎖帳號", "description": "Button text to display in overlay when the account is locked." }, + "unlockAccountAria": { + "message": "Unlock your account, opens in a new window", + "description": "Screen reader text (aria-label) for unlock account button in overlay" + }, "fillCredentialsFor": { "message": "填入登入資訊給", "description": "Screen reader text for when overlay item is in focused" @@ -2994,6 +3080,30 @@ "message": "新增密碼庫項目", "description": "Screen reader text (aria-label) for new item button in overlay" }, + "newLogin": { + "message": "New login", + "description": "Button text to display within inline menu when there are no matching items on a login field" + }, + "addNewLoginItemAria": { + "message": "Add new vault login item, opens in a new window", + "description": "Screen reader text (aria-label) for new login button within inline menu" + }, + "newCard": { + "message": "New card", + "description": "Button text to display within inline menu when there are no matching items on a credit card field" + }, + "addNewCardItemAria": { + "message": "Add new vault card item, opens in a new window", + "description": "Screen reader text (aria-label) for new card button within inline menu" + }, + "newIdentity": { + "message": "New identity", + "description": "Button text to display within inline menu when there are no matching items on an identity field" + }, + "addNewIdentityItemAria": { + "message": "Add new vault identity item, opens in a new window", + "description": "Screen reader text (aria-label) for new identity button within inline menu" + }, "bitwardenOverlayMenuAvailable": { "message": "Bitwarden 自動填入選單可用。按下箭頭鍵來選擇。", "description": "Screen reader text for announcing when the overlay opens on the page" @@ -3110,8 +3220,8 @@ "invalidFilePassword": { "message": "檔案密碼無效,請使用您當初匯出檔案時輸入的密碼。" }, - "importDestination": { - "message": "匯入目的地" + "destination": { + "message": "Destination" }, "learnAboutImportOptions": { "message": "瞭解更多匯入選項" @@ -3343,7 +3453,7 @@ "placeholders": { "domain": { "content": "$1", - "example": "google.com" + "example": "duckduckgo.com" } } }, @@ -3351,12 +3461,36 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "confirmContinueToBrowserSettingsTitle": { + "message": "Continue to browser settings?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" + }, + "confirmContinueToHelpCenter": { + "message": "Continue to Help Center?", + "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" + }, + "confirmContinueToHelpCenterPasswordManagementContent": { + "message": "Change your browser's autofill and password management settings.", + "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": "You can view and set extension shortcuts in your browser's settings.", + "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": "Change your browser's autofill and password management settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" + }, + "confirmContinueToBrowserKeyboardShortcutSettingsContent": { + "message": "You can view and set extension shortcuts in your browser's settings.", + "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" + }, "overrideDefaultBrowserAutofillTitle": { "message": "Make Bitwarden your default password manager?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { @@ -3474,8 +3608,8 @@ "noValuesToCopy": { "message": "No values to copy" }, - "assignCollections": { - "message": "Assign collections" + "assignToCollections": { + "message": "Assign to collections" }, "copyEmail": { "message": "Copy email" @@ -3643,6 +3777,10 @@ } } }, + "cardNumberEndsWith": { + "message": "card number ends with", + "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." + }, "loginCredentials": { "message": "Login credentials" }, @@ -3667,10 +3805,16 @@ "loading": { "message": "Loading" }, + "data": { + "message": "Data" + }, "assign": { "message": "Assign" }, - "bulkCollectionAssignmentDialogDescription": { + "bulkCollectionAssignmentDialogDescriptionSingular": { + "message": "Only organization members with access to these collections will be able to see the item." + }, + "bulkCollectionAssignmentDialogDescriptionPlural": { "message": "Only organization members with access to these collections will be able to see the items." }, "bulkCollectionAssignmentWarning": { @@ -3771,21 +3915,33 @@ "selectCollectionsToAssign": { "message": "Select collections to assign" }, - "personalItemsTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to the selected organization. You will no longer own these items.", + "personalItemTransferWarningSingular": { + "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + }, + "personalItemsTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" } } }, - "personalItemsWithOrgTransferWarning": { - "message": "$PERSONAL_ITEMS_COUNT$ will be permanently transferred to $ORG$. You will no longer own these items.", + "personalItemWithOrgTransferWarningSingular": { + "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "placeholders": { + "org": { + "content": "$1", + "example": "Organization name" + } + } + }, + "personalItemsWithOrgTransferWarningPlural": { + "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", "placeholders": { "personal_items_count": { "content": "$1", - "example": "2 items" + "example": "2" }, "org": { "content": "$2", @@ -3808,6 +3964,24 @@ } } }, + "itemsMovedToOrg": { + "message": "Items moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, + "itemMovedToOrg": { + "message": "Item moved to $ORGNAME$", + "placeholders": { + "orgname": { + "content": "$1", + "example": "Company Name" + } + } + }, "reorderFieldDown": { "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", "placeholders": { @@ -3824,5 +3998,8 @@ "example": "3" } } + }, + "itemLocation": { + "message": "Item Location" } } diff --git a/apps/browser/store/locales/el/copy.resx b/apps/browser/store/locales/el/copy.resx index f5138c7543f..5c1d99de2a2 100644 --- a/apps/browser/store/locales/el/copy.resx +++ b/apps/browser/store/locales/el/copy.resx @@ -149,13 +149,13 @@ Το Bitwarden διεξάγει τακτικά ολοκληρωμένους ελέγχους ασφαλείας από τρίτους με αξιόλογες εταιρείες ασφαλείας. Αυτοί οι ετήσιοι έλεγχοι περιλαμβάνουν αξιολογήσεις πηγαίου κώδικα και δοκιμές διείσδυσης σε όλες τις IP του Bitwarden, τους διακομιστές και τις εφαρμογές ιστού. Προηγμένο 2FA -Ασφαλίστε τη σύνδεσή σας με εφαρμογή αυθεντικοποίησης, κωδικούς που αποστέλλονται μέσω ηλεκτρονικού ταχυδρομείου ή διαπιστευτήρια FIDO2 WebAuthn, όπως ένα φυσικό κλειδί ασφαλείας ή ένα κλειδί πρόσβασης. +Ασφαλίστε τη σύνδεσή σας με εφαρμογή αυθεντικοποίησης, κωδικούς που αποστέλλονται μέσω ηλ. ταχυδρομείου ή διαπιστευτήρια FIDO2 WebAuthn, όπως ένα φυσικό κλειδί ασφαλείας ή ένα κλειδί πρόσβασης. Bitwarden Send Μεταδώστε δεδομένα απευθείας σε άλλους, διατηρώντας κρυπτογραφημένη ασφάλεια από άκρο σε άκρο και περιορίζοντας την έκθεση. Ενσωματωμένη γεννήτρια -Δημιουργήστε μεγάλους, σύνθετους και ξεχωριστούς κωδικούς πρόσβασης και μοναδικά ονόματα χρήστη για κάθε ιστότοπο που επισκέπτεστε. Ενσωματώστε παρόχους ψευδώνυμων για τη διεύθυνση ηλεκτρονικού ταχυδρομείου για επιπλέον προστασία της ιδιωτικής σας ζωής. +Δημιουργήστε μεγάλους, σύνθετους και ξεχωριστούς κωδικούς πρόσβασης και μοναδικά ονόματα χρήστη για κάθε ιστότοπο που επισκέπτεστε. Ενσωματώστε παρόχους ψευδώνυμων για τη διεύθυνση ηλ. ταχυδρομείου για επιπλέον προστασία της ιδιωτικής σας ζωής. Παγκόσμιες μεταφράσεις Υπάρχουν μεταφράσεις του Bitwarden για περισσότερες από 60 γλώσσες, μεταφρασμένες από την παγκόσμια κοινότητα μέσω του Crowdin. From 7594ebead23fdce480a5e6cdb96a9f533ce38865 Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:46:06 -0500 Subject: [PATCH 12/46] [PM-9953][PM-9963] Collections Reprompt and Org assignment (#10194) * prompt for master password for assigning-collections * only pass collections that are within the cipher's org * remove type=button on anchor element --- .../assign-collections.component.ts | 15 +++++++++++++-- .../item-more-options.component.html | 7 +------ .../item-more-options.component.ts | 11 +++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts b/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts index a3ebadb7e2b..a0ab3401f4d 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/assign-collections/assign-collections.component.ts @@ -66,10 +66,21 @@ export class AssignCollections { combineLatest([$cipher, this.collectionService.decryptedCollections$]) .pipe(takeUntilDestroyed(), first()) .subscribe(([cipherView, collections]) => { + let availableCollections = collections.filter((c) => !c.readOnly); + const organizationId = (cipherView?.organizationId as OrganizationId) ?? null; + + // If the cipher is already a part of an organization, + // only show collections that belong to that organization + if (organizationId) { + availableCollections = availableCollections.filter( + (c) => c.organizationId === organizationId, + ); + } + this.params = { ciphers: [cipherView], - organizationId: (cipherView?.organizationId as OrganizationId) ?? null, - availableCollections: collections.filter((c) => !c.readOnly), + organizationId, + availableCollections, }; }); } diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html index cd2e849f95b..d17269303ee 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html @@ -28,12 +28,7 @@ {{ "clone" | i18n }} - + {{ "assignToCollections" | i18n }} diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts index 23ff9593099..4857703d3b1 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts @@ -152,4 +152,15 @@ export class ItemMoreOptionsComponent { } as AddEditQueryParams, }); } + + /** Prompts for password when necessary then navigates to the assign collections route */ + async conditionallyNavigateToAssignCollections() { + if (this.cipher.reprompt && !(await this.passwordRepromptService.showPasswordPrompt())) { + return; + } + + await this.router.navigate(["/assign-collections"], { + queryParams: { cipherId: this.cipher.id }, + }); + } } From a43786872722f9259fba94096eaa0c6f5ee0c4de Mon Sep 17 00:00:00 2001 From: Jake Fink Date: Fri, 26 Jul 2024 14:23:20 -0400 Subject: [PATCH 13/46] move initialization of UV service dep (#10290) --- apps/cli/src/service-container.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/cli/src/service-container.ts b/apps/cli/src/service-container.ts index cc533027328..f9bff5c6d04 100644 --- a/apps/cli/src/service-container.ts +++ b/apps/cli/src/service-container.ts @@ -625,6 +625,8 @@ export class ServiceContainer { const lockedCallback = async (userId?: string) => await this.cryptoService.clearStoredUserKey(KeySuffixOptions.Auto); + this.userVerificationApiService = new UserVerificationApiService(this.apiService); + this.userVerificationService = new UserVerificationService( this.cryptoService, this.accountService, @@ -729,8 +731,6 @@ export class ServiceContainer { this.auditService = new AuditService(this.cryptoFunctionService, this.apiService); - this.userVerificationApiService = new UserVerificationApiService(this.apiService); - this.eventUploadService = new EventUploadService( this.apiService, this.stateProvider, From d4a1c1a997f067f5b7e6bc07ed1ad6dab52d1fd9 Mon Sep 17 00:00:00 2001 From: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:06:48 -0500 Subject: [PATCH 14/46] [SM-1365] Fix organization ID not updating on overview swaps (#10189) * fix org id not being updated in new-menu on org swaps * fix org suspended component --- .../secrets-manager/shared/new-menu.component.ts | 14 +++++--------- .../shared/org-suspended.component.ts | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.ts index d2533d8dbf7..ce499ee9bda 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; -import { Subject, takeUntil, concatMap, map } from "rxjs"; +import { Subject, takeUntil, concatMap } from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { DialogService } from "@bitwarden/components"; @@ -36,16 +36,12 @@ export class NewMenuComponent implements OnInit, OnDestroy { ngOnInit() { this.route.params .pipe( - concatMap((params) => - this.organizationService - .get$(params.organizationId) - .pipe(map((organization) => ({ params, organization }))), - ), + concatMap(async (params) => await this.organizationService.get(params.organizationId)), takeUntil(this.destroy$), ) - .subscribe((mapResult) => { - this.organizationId = mapResult?.params?.organizationId; - this.organizationEnabled = mapResult?.organization?.enabled; + .subscribe((org) => { + this.organizationId = org.id; + this.organizationEnabled = org.enabled; }); } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/org-suspended.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/org-suspended.component.ts index 1683d447906..e0293ba5316 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/org-suspended.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/org-suspended.component.ts @@ -16,7 +16,7 @@ export class OrgSuspendedComponent { protected NoAccess: Icon = Icons.NoAccess; protected organizationName$ = this.route.params.pipe( - concatMap((params) => this.organizationService.get$(params.organizationId)), + concatMap(async (params) => await this.organizationService.get(params.organizationId)), map((org) => org?.name), ); } From 885464d81982ade74e4d4eb4e921078943a139f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 12:27:15 +0000 Subject: [PATCH 15/46] Autosync the updated translations (#10313) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/az/messages.json | 20 ++++++++++---------- apps/desktop/src/locales/de/messages.json | 10 +++++----- apps/desktop/src/locales/el/messages.json | 2 +- apps/desktop/src/locales/fi/messages.json | 2 +- apps/desktop/src/locales/hr/messages.json | 2 +- apps/desktop/src/locales/lv/messages.json | 6 +++--- apps/desktop/src/locales/uk/messages.json | 10 +++++----- apps/desktop/src/locales/zh_CN/messages.json | 4 ++-- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index fa62ef1663d..6e8967e5a35 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -552,10 +552,10 @@ "message": "Ana parol ipucusu" }, "joinOrganization": { - "message": "Join organization" + "message": "Təşkilata qoşul" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Bu ana parol təyin edərək bu təşkilata qoşulmağı tamamlayın." }, "settings": { "message": "Ayarlar" @@ -1417,7 +1417,7 @@ "description": "ex. Register as an accessibility user at hcaptcha.com" }, "copyPasteLink": { - "message": "E-poçtunuza göndərilən bağlantını kopyalayıb aşağıda yapışdırın" + "message": "E-poçtunuza göndərilən keçidi kopyalayıb aşağıda yapışdırın" }, "enterhCaptchaUrl": { "message": "hCaptcha əlçatımlılıq çərəzini yükləmək üçün ünvanı daxil edin", @@ -1878,11 +1878,11 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLink": { - "message": "\"Send\" bağlantısı", + "message": "\"Send\" keçidi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinkLabel": { - "message": "\"Send\" bağlantısı", + "message": "\"Send\" keçidi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "textHiddenByDefault": { @@ -1938,11 +1938,11 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copySendLinkToClipboard": { - "message": "Send bağlantısını lövhəyə kopyala", + "message": "Send keçidini lövhəyə kopyala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copySendLinkOnSave": { - "message": "Saxladıqdan sonra bu \"Send\"in paylaşma bağlantısını lövhəmə kopyala." + "message": "Saxladıqdan sonra bu \"Send\"in paylaşma keçidini lövhəmə kopyala." }, "sendDisabled": { "message": "Send sıradan çıxarıldı", @@ -1953,7 +1953,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Bağlantını kopyala" + "message": "Keçidi kopyala" }, "disabled": { "message": "Sıradan çıxarıldı" @@ -2100,7 +2100,7 @@ "message": "Anbar vaxt bitişi, təşkilatınız tərəfindən ayarlanan məhdudiyyətləri aşır." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Dəvət qəbul edildi" }, "resetPasswordPolicyAutoEnroll": { "message": "Avtomatik qeydiyyat" @@ -2827,7 +2827,7 @@ "message": "Yararsız fayl parolu, lütfən xaricə köçürmə faylını yaradarkən daxil etdiyiniz parolu istifadə edin." }, "destination": { - "message": "Destination" + "message": "Hədəf" }, "learnAboutImportOptions": { "message": "Daxilə köçürmə seçimlərinizi öyrənin" diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index cee6ad0f4bb..47f07af7c33 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -552,10 +552,10 @@ "message": "Master-Passwort-Hinweis" }, "joinOrganization": { - "message": "Join organization" + "message": "Organisation beitreten" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Schließe den Beitritt zu dieser Organisation ab, indem du ein Master-Passwort festlegst." }, "settings": { "message": "Einstellungen" @@ -2100,7 +2100,7 @@ "message": "Dein Tresor-Timeout überschreitet die von deinem Unternehmen festgelegten Beschränkungen." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Einladung angenommen" }, "resetPasswordPolicyAutoEnroll": { "message": "Automatische Registrierung" @@ -2827,7 +2827,7 @@ "message": "Ungültiges Dateipasswort. Bitte verwende das Passwort, das du beim Erstellen der Exportdatei eingegeben hast." }, "destination": { - "message": "Destination" + "message": "Ziel" }, "learnAboutImportOptions": { "message": "Erfahre mehr über deine Importoptionen" @@ -3024,6 +3024,6 @@ } }, "data": { - "message": "Data" + "message": "Daten" } } diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index b64dbaaa9a8..9a4b3e0a099 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -736,7 +736,7 @@ "message": "Καθορίστε τη βασική διεύθυνση URL, της εγκατάστασης του Bitwarden που φιλοξενείται στο χώρο σας." }, "selfHostedBaseUrlHint": { - "message": "Καθορίστε τη βασική διεύθυνση URL της εγκατάστασης Bitwarden στον τομέα σας. Παράδειγμα: https://bitwarden.company.com" + "message": "Καθορίστε το βασικό URL της εγκατάστασης Bitwarden που φιλοξενείται στο χώρο σας. Παράδειγμα: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { "message": "Για προχωρημένη παραμετροποίηση, μπορείτε να ορίσετε ανεξάρτητα το βασικό URL κάθε υπηρεσίας." diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 7b8f8c691a1..6c1fa599281 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -2429,7 +2429,7 @@ "message": "Laitteellesi on lähetetty ilmoitus." }, "fingerprintMatchInfo": { - "message": "Varmista, että holvisi on avattu ja tunnistelauseke täsmää toisella laitteella." + "message": "Varmista, että vahvistavan laitteen holvi on avattu ja että se näyttää saman tunnistelausekkeen." }, "fingerprintPhraseHeader": { "message": "Tunnistelauseke" diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index 895ec2ab378..239b93f3515 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -601,7 +601,7 @@ "message": "Potvrda glavne lozinke se ne podudara." }, "newAccountCreated": { - "message": "Tvoj novi račun je kreiran! Sada se možeš prijaviti." + "message": "Tvoj novi račun je stvoren! Sada se možeš prijaviti." }, "masterPassSent": { "message": "Poslali smo e-poštu s podsjetnikom glavne lozinke." diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 768bd8b83d6..ef698a0b35c 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -552,10 +552,10 @@ "message": "Galvenās paroles norāde" }, "joinOrganization": { - "message": "Join organization" + "message": "Pievienoties apvienībai" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Pabeigt pievienošanos šai apvienībai ar galvenās paroles iestatīšanu." }, "settings": { "message": "Iestatījumi" @@ -2100,7 +2100,7 @@ "message": "Glabātavas noildze pārsniedz apvienības uzstādītos ierobežojumus." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Uzaicinājums apstiprināts" }, "resetPasswordPolicyAutoEnroll": { "message": "Automātiska ievietošana sarakstā" diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index b787172d170..d8de277cf84 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -552,10 +552,10 @@ "message": "Підказка для головного пароля" }, "joinOrganization": { - "message": "Join organization" + "message": "Приєднатися до організації" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Завершіть приєднання до цієї організації, встановивши головний пароль." }, "settings": { "message": "Налаштування" @@ -2100,7 +2100,7 @@ "message": "Час очікування сховища перевищує обмеження, встановлені вашою організацією." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Запрошення прийнято" }, "resetPasswordPolicyAutoEnroll": { "message": "Автоматичне подання запиту" @@ -2827,7 +2827,7 @@ "message": "Неправильний пароль файлу. Використайте пароль, який ви вводили під час створення експортованого файлу." }, "destination": { - "message": "Destination" + "message": "Призначення" }, "learnAboutImportOptions": { "message": "Дізнайтеся про параметри імпорту" @@ -3024,6 +3024,6 @@ } }, "data": { - "message": "Data" + "message": "Дані" } } diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 099a9b24665..36f4bad1a07 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -2827,7 +2827,7 @@ "message": "无效的文件密码,请使用您创建导出文件时输入的密码。" }, "destination": { - "message": "Destination" + "message": "目的地" }, "learnAboutImportOptions": { "message": "了解您的导入选项" @@ -3024,6 +3024,6 @@ } }, "data": { - "message": "Data" + "message": "数据" } } From 73429a21502838642f38d7a1ef23ffb6a0b008f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 12:28:50 +0000 Subject: [PATCH 16/46] Autosync the updated translations (#10312) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/az/messages.json | 82 +-- apps/browser/src/_locales/bg/messages.json | 20 +- apps/browser/src/_locales/de/messages.json | 82 +-- apps/browser/src/_locales/fi/messages.json | 66 +- apps/browser/src/_locales/hr/messages.json | 574 +++++++++--------- apps/browser/src/_locales/hu/messages.json | 20 +- apps/browser/src/_locales/ja/messages.json | 26 +- apps/browser/src/_locales/lv/messages.json | 26 +- apps/browser/src/_locales/sk/messages.json | 16 +- apps/browser/src/_locales/uk/messages.json | 48 +- apps/browser/src/_locales/zh_CN/messages.json | 34 +- apps/browser/store/locales/hr/copy.resx | 58 +- 12 files changed, 526 insertions(+), 526 deletions(-) diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index e9b0c46e50e..61e54ba6cd0 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -14,7 +14,7 @@ "message": "Güvənli anbarınıza müraciət etmək üçün giriş edin və ya yeni bir hesab yaradın." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Dəvət qəbul edildi" }, "createAccount": { "message": "Hesab yarat" @@ -72,10 +72,10 @@ "message": "Ana parol ipucu (ixtiyari)" }, "joinOrganization": { - "message": "Join organization" + "message": "Təşkilata qoşul" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Bu ana parol təyin edərək bu təşkilata qoşulmağı tamamlayın." }, "tab": { "message": "Vərəq" @@ -799,7 +799,7 @@ "message": "Anbarınızda tapılmayan bir elementin əlavə edilməsi soruşulsun. Giriş etmiş bütün hesablara aiddir." }, "showCardsInVaultView": { - "message": "Show cards as Autofill suggestions on Vault view" + "message": "Kartları, Anbar görünüşündə Avto-doldurma təklifləri olaraq göstər" }, "showCardsCurrentTab": { "message": "Kartları Vərəq səhifəsində göstər" @@ -808,7 +808,7 @@ "message": "Asan avto-doldurma üçün Vərəq səhifəsində kart elementlərini sadalayın." }, "showIdentitiesInVaultView": { - "message": "Show identifies as Autofill suggestions on Vault view" + "message": "Kimlikləri, Anbar görünüşündə Avto-doldurma təklifləri olaraq göstər" }, "showIdentitiesCurrentTab": { "message": "Vərəq səhifəsində kimlikləri göstər" @@ -1243,16 +1243,16 @@ "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Autofill suggestions" + "message": "Avto-doldurma təklifləri" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "Avto-doldurma təkliflərini form xanalarında göstər" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "İkon seçildikdə təklifləri göstər" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "Giriş etmiş bütün hesablara aiddir." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Ziddiyyətləri önləmək üçün brauzerinizin daxili parol meneceri ayarlarını söndürün." @@ -1273,7 +1273,7 @@ "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "Səhifə yüklənəndə avto-doldur" }, "enableAutoFillOnPageLoad": { "message": "Səhifə yüklənəndə avto-doldurmanı fəallaşdır" @@ -1282,7 +1282,7 @@ "message": "Giriş formu aşkarlananda, səhifə yüklənən zaman formu avto-doldurma icra edilsin." }, "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "message": "$OPENTAG$Xəbərdarlıq:$CLOSETAG$ Təhlükəsizliyi pozulmuş və ya güvənilməyən veb saytlar, səhifə yüklənəndə avto-doldurmanı istifadə edə bilər.", "placeholders": { "openTag": { "content": "$1", @@ -1298,7 +1298,7 @@ "message": "Təhlükəli və ya güvənilməyən veb saytlar, səhifə yüklənərkən avto-doldurmanı istifadə edə bilər." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "Risklər haqqında daha ətraflı" }, "learnMoreAboutAutofill": { "message": "Avto-doldurma haqqında daha ətraflı" @@ -2090,7 +2090,7 @@ "message": "Parolla qorunan" }, "copyLink": { - "message": "Copy link" + "message": "Keçidi kopyala" }, "copySendLink": { "message": "\"Send\" keçidini kopyala", @@ -2753,10 +2753,10 @@ "message": "Avto-doldurma ayarları" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Avto-doldurma qısayolu" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "Qısayolu dəyişdir" }, "autofillShortcut": { "message": "Avto-doldurma klaviatura qısayolu" @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Avto-doldurma təkliflərinə baxmaq üçün hesabınızın kilidini açın", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Hesabınızın kilidini açın, yeni bir pəncərədə açılır", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Yeni giriş", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Yeni anbar giriş elementini əlavə et, yeni bir pəncərədə açılır", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Yeni kart", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Yeni anbar kart elementini əlavə et, yeni bir pəncərədə açılır", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Yeni kimlik", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Yeni anbar kimlik elementini əlavə et, yeni bir pəncərədə açılır", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3221,7 +3221,7 @@ "message": "Yararsız fayl parolu, lütfən xaricə köçürmə faylını yaradarkən daxil etdiyiniz parolu istifadə edin." }, "destination": { - "message": "Destination" + "message": "Hədəf" }, "learnAboutImportOptions": { "message": "Daxilə köçürmə seçimlərinizi öyrənin" @@ -3462,27 +3462,27 @@ "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "Brauzer ayarları ilə davam edilsin?", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "Kömək Mərkəzi ilə davam edilsin?", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "Brauzerinizin avto-doldurma və parol idarəsi ayarlarını dəyişdirin.", "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": "You can view and set extension shortcuts in your browser's settings.", + "message": "Uzantı qısayollarını brauzerinizin ayarlarında görə və ayarlaya bilərsiniz.", "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": "Change your browser's autofill and password management settings.", + "message": "Brauzerinizin avto-doldurma və parol idarəsi ayarlarını dəyişdirin.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "Uzantı qısayollarını brauzerinizin ayarlarında görə və ayarlaya bilərsiniz.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { @@ -3609,7 +3609,7 @@ "message": "Kopyalanacaq dəyər yoxdur" }, "assignToCollections": { - "message": "Assign to collections" + "message": "Kolleksiyalara təyin et" }, "copyEmail": { "message": "E-poçtu kopyala" @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "kart nömrəsinin sonu", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { @@ -3812,10 +3812,10 @@ "message": "Təyin et" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Yalnız bu kolleksiyalara müraciəti olan təşkilat üzvləri bu elementi görə biləcək." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Yalnız bu kolleksiyalara müraciəti olan təşkilat üzvləri bu elementləri görə biləcək." }, "bulkCollectionAssignmentWarning": { "message": "$TOTAL_COUNT$ element seçmisiniz. Düzəliş icazəniz olmadığı üçün $READONLY_COUNT$ elementi güncəlləyə bilməzsiniz.", @@ -3916,10 +3916,10 @@ "message": "Təyin ediləcək kolleksiyaları seçin" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 element seçilmiş təşkilata birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ element seçilmiş təşkilata birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", "placeholders": { "personal_items_count": { "content": "$1", @@ -3928,7 +3928,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 element $ORG$ təşkilatına birdəfəlik transfer ediləcək. Artıq bu elementə sahib olmaya bilməyəcəksiniz.", "placeholders": { "org": { "content": "$1", @@ -3937,7 +3937,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ element $ORG$ təşkilatına birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", "placeholders": { "personal_items_count": { "content": "$1", @@ -3965,7 +3965,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Elementlər bura daşındı: $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3974,7 +3974,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Element bura daşındı: $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4000,6 +4000,6 @@ } }, "itemLocation": { - "message": "Item Location" + "message": "Element yeri" } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 5c0c7b9ed1e..3ab1f47fd91 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -2090,7 +2090,7 @@ "message": "Защита с парола" }, "copyLink": { - "message": "Copy link" + "message": "Копиране на връзката" }, "copySendLink": { "message": "Копиране на връзката към изпратеното", @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Отключете регистрацията си, за да видите предложение за автоматично попълване", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Отклюване на регистрацията, отваря се в нов прозорец", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Нов елемент за вписване", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Добавяне на нов елемент за вписване в трезора, отваря се в нов прозорец", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Нова карта", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Добавяне на нов елемент за карта в трезора, отваря се в нов прозорец", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Нова самоличност", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Добавяне на нов елемент за идентичност в трезора, отваря се в нов прозорец", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "номерът на картата завършва с", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index a2034eda73f..2dd0ff5a367 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -14,7 +14,7 @@ "message": "Melde dich an oder erstelle ein neues Konto, um auf deinen Tresor zuzugreifen." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Einladung angenommen" }, "createAccount": { "message": "Konto erstellen" @@ -72,10 +72,10 @@ "message": "Master-Passwort-Hinweis (optional)" }, "joinOrganization": { - "message": "Join organization" + "message": "Organisation beitreten" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Schließe den Beitritt zu dieser Organisation ab, indem du ein Master-Passwort festlegst." }, "tab": { "message": "Tab" @@ -799,7 +799,7 @@ "message": "Nach dem Hinzufügen eines Eintrags fragen, wenn er nicht in deinem Tresor gefunden wurde. Gilt für alle angemeldeten Konten." }, "showCardsInVaultView": { - "message": "Show cards as Autofill suggestions on Vault view" + "message": "Karten als Vorschläge zum Auto-Ausfüllen in der Tresor-Ansicht anzeigen" }, "showCardsCurrentTab": { "message": "Karten auf Tab Seite anzeigen" @@ -808,7 +808,7 @@ "message": "Karten-Einträge auf der Tab Seite anzeigen, um das Auto-Ausfüllen zu vereinfachen." }, "showIdentitiesInVaultView": { - "message": "Show identifies as Autofill suggestions on Vault view" + "message": "Identitäten als Vorschläge zum Auto-Ausfüllen in der Tresor-Ansicht anzeigen" }, "showIdentitiesCurrentTab": { "message": "Identitäten auf Tab Seite anzeigen" @@ -1243,16 +1243,16 @@ "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Autofill suggestions" + "message": "Vorschläge zum Auto-Ausfüllen" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "Vorschläge zum Auto-Ausfüllen in Formularfeldern anzeigen" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "Vorschläge anzeigen, wenn Symbol ausgewählt ist" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "Gilt für alle angemeldeten Konten." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Deaktiviere die Einstellungen des eingebauten Passwort-Managers deines Browsers, um Konflikte zu vermeiden." @@ -1273,7 +1273,7 @@ "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "Auto-Ausfüllen beim Laden einer Seite" }, "enableAutoFillOnPageLoad": { "message": "Auto-Ausfüllen beim Laden einer Seite aktivieren" @@ -1282,7 +1282,7 @@ "message": "Wenn eine Anmeldemaske erkannt wird, die Zugangsdaten automatisch ausfüllen während die Webseite lädt." }, "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "message": "$OPENTAG$Warnung:$CLOSETAG$ Kompromittierte oder nicht vertrauenswürdige Websites können Auto-Ausfüllen beim Laden einer Seite missbrauchen.", "placeholders": { "openTag": { "content": "$1", @@ -1298,7 +1298,7 @@ "message": "Kompromittierte oder nicht vertrauenswürdige Websites können Auto-Ausfüllen beim Laden der Seite ausnutzen." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "Erfahre mehr über Risiken" }, "learnMoreAboutAutofill": { "message": "Erfahre mehr über Auto-Ausfüllen" @@ -2090,7 +2090,7 @@ "message": "Passwortgeschützt" }, "copyLink": { - "message": "Copy link" + "message": "Link kopieren" }, "copySendLink": { "message": "Send-Link kopieren", @@ -2753,10 +2753,10 @@ "message": "Auto-Ausfüllen Einstellungen" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Auto-Ausfüllen Tastenkombination" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "Tastenkombination ändern" }, "autofillShortcut": { "message": "Auto-Ausfüllen Tastaturkürzel" @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Entsperre dein Konto, um Auto-Ausfüllen-Vorschläge anzuzeigen", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Dein Konto entsperren, öffnet sich in einem neuen Fenster", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Neue Zugangsdaten", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Neuen Tresor-Zugangsdateneintrag hinzufügen, öffnet sich in einem neuen Fenster", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Neue Karte", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Neuen Tresor-Karteneintrag hinzufügen, öffnet sich in einem neuen Fenster", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Neue Identität", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Neuen Tresor-Identitätseintrag hinzufügen, öffnet sich in einem neuen Fenster", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3221,7 +3221,7 @@ "message": "Ungültiges Dateipasswort. Bitte verwende das Passwort, das du beim Erstellen der Exportdatei eingegeben hast." }, "destination": { - "message": "Destination" + "message": "Ziel" }, "learnAboutImportOptions": { "message": "Erfahre mehr über deine Importoptionen" @@ -3462,27 +3462,27 @@ "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "Weiter zu den Browsereinstellungen?", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "Weiter zum Hilfezentrum?", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "Ändere die Auto-Ausfüllen- und Passwort-Verwaltungseinstellungen deines Browsers.", "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": "You can view and set extension shortcuts in your browser's settings.", + "message": "Du kannst Tastenkombinationen für Erweiterungen in den Einstellungen deines Browsers anzeigen und festlegen.", "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": "Change your browser's autofill and password management settings.", + "message": "Ändere die Auto-Ausfüllen- und Passwort-Verwaltungseinstellungen deines Browsers.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "Du kannst Tastenkombinationen für Erweiterungen in den Einstellungen deines Browsers anzeigen und festlegen.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { @@ -3609,7 +3609,7 @@ "message": "Keine Werte zum Kopieren" }, "assignToCollections": { - "message": "Assign to collections" + "message": "Sammlungen zuweisen" }, "copyEmail": { "message": "E-Mail-Adresse kopieren" @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "Kartennummer endet mit", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { @@ -3806,16 +3806,16 @@ "message": "Wird geladen" }, "data": { - "message": "Data" + "message": "Daten" }, "assign": { "message": "Zuweisen" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Nur Organisationsmitglieder mit Zugriff auf diese Sammlungen können die Einträge sehen." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Nur Organisationsmitglieder mit Zugriff auf diese Sammlungen können die Einträge sehen." }, "bulkCollectionAssignmentWarning": { "message": "Du hast $TOTAL_COUNT$ Einträge ausgewählt. Du kannst $READONLY_COUNT$ der Einträge nicht aktualisieren, da du keine Bearbeitungsrechte hast.", @@ -3916,10 +3916,10 @@ "message": "Zu zuweisende Sammlungen auswählen" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 Eintrag wird dauerhaft an die ausgewählte Organisation übertragen. Du wirst diesen Eintrag nicht mehr besitzen." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an die ausgewählte Organisation übertragen. Du wirst diese Einträge nicht mehr besitzen.", "placeholders": { "personal_items_count": { "content": "$1", @@ -3928,7 +3928,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 Eintrag wird dauerhaft an $ORG$ übertragen. Du wirst diesen Eintrag nicht mehr besitzen.", "placeholders": { "org": { "content": "$1", @@ -3937,7 +3937,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an $ORG$ übertragen. Du wirst diese Einträge nicht mehr besitzen.", "placeholders": { "personal_items_count": { "content": "$1", @@ -3965,7 +3965,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Einträge verschoben nach $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3974,7 +3974,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Eintrag verschoben nach $ORGNAME$", "placeholders": { "orgname": { "content": "$1", diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 7552425f827..8fadade5863 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -75,7 +75,7 @@ "message": "Liity organisaatioon" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Viimeistele organisaatioon liittyminen asettamalla pääsalasana." + "message": "Viimeistele liittyminen organisaatioon asettamalla pääsalasana." }, "tab": { "message": "Välilehti" @@ -126,7 +126,7 @@ "message": "Automaattitäytä kortti" }, "autoFillIdentity": { - "message": "Automaattitäytä identiteetti" + "message": "Automaattitäytä henkilöllisyys" }, "generatePasswordCopied": { "message": "Luo salasana (leikepöydälle)" @@ -150,7 +150,7 @@ "message": "Lisää kortti" }, "addIdentityMenu": { - "message": "Lisää identiteetti" + "message": "Lisää henkilöllisyys" }, "unlockVaultMenu": { "message": "Avaa holvisi" @@ -487,7 +487,7 @@ "message": "Selaimesi ei tue helppoa leikepöydälle kopiointia. Kopioi kohde manuaalisesti." }, "verifyIdentity": { - "message": "Vahvista henkilöllisyys" + "message": "Vahvista henkilöllisyytesi" }, "yourVaultIsLocked": { "message": "Holvisi on lukittu. Jatka vahvistamalla henkilöllisyytesi." @@ -799,7 +799,7 @@ "message": "Ehdota kohteen tallennusta, jos holvistasi ei vielä löydy vastaavaa kohdetta. Koskee kaikkia kirjautuneita tilejä." }, "showCardsInVaultView": { - "message": "Näytä kortit automaattitäytön ehdotuksina Holvit-näkymässä" + "message": "Näytä kortit automaattitäytön ehdotuksina Holvi-näkymässä" }, "showCardsCurrentTab": { "message": "Näytä kortit välilehtiosiossa" @@ -808,7 +808,7 @@ "message": "Kortit näytetään laajennuksen välilehtisivulla niiden automaattisen täytön helpottamiseksi." }, "showIdentitiesInVaultView": { - "message": "Näytä identiteetit automaattitäytön ehdotuksina Holvit-näkymässä" + "message": "Näytä henkilöllisyydet automaattitäytön ehdotuksina Holvi-näkymässä" }, "showIdentitiesCurrentTab": { "message": "Näytä henkilöllisyydet välilehtiosiossa" @@ -1249,13 +1249,13 @@ "message": "Näytä automaattitäytön ehdotukset lomakekentissä" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Näytä ehdotukset, kun kuvake on valittu" + "message": "Näytä ehdotukset kun kuvaketta painetaan" }, "showInlineMenuOnFormFieldsDescAlt": { "message": "Koskee kaikkia kirjautuneita tilejä." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Poista selaimesi sisäänrakennettu salasanahallinta käytöstä sen asetuksista ristiriitojen välttämiseksi." + "message": "Poista käytöstä selaimesi asetuksista sen sisäänrakennettu salasanahallinta ristiriitojen välttämiseksi." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Muokkaa selaimen asetuksia" @@ -1282,7 +1282,7 @@ "message": "Automaattinen täyttö suoritetaan sivun avautuessa, jos sivulla havaitaan kirjautumislomake." }, "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Varoitus:$CLOSETAG$ Vaarantuneet tai epäluotettavat verkkosivustot voivat hyväksikäyttää automaattitäyttöä sivun latauksen yhteydessä.", + "message": "$OPENTAG$Varoitus:$CLOSETAG$ Vaarantuneet tai epäluotettavat sivustot voivat hyväksikäyttää sivun avautuessa suoritettavaa automaattista täyttöä.", "placeholders": { "openTag": { "content": "$1", @@ -1295,10 +1295,10 @@ } }, "experimentalFeature": { - "message": "Vaarantuneet tai epäluotettavat sivustot voivat väärinkäyttää sivun avautuessa suoritettavaa automaattista täyttöä." + "message": "Vaarantuneet tai epäluotettavat sivustot voivat hyväksikäyttää sivun avautuessa suoritettavaa automaattista täyttöä." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Lue lisää riskeistä" + "message": "Lisätietoja riskeistä" }, "learnMoreAboutAutofill": { "message": "Lisätietoja automaattitäytöstä" @@ -1307,7 +1307,7 @@ "message": "Kirjautumistietojen automaattitäytön oletusasetus" }, "defaultAutoFillOnPageLoadDesc": { - "message": "Automaattinen täyttö on mahdollista ottaa käyttöön tai poistaa käytöstä kirjautumistietokohtaisesti kirjautumistetoa muokkaamalla." + "message": "Automaattinen täyttö voidaan ottaa käyttöön tai poistaa käytöstä kohdekohtaisesti muokkaamalla yksittäisiä kirjautumistietoja." }, "itemAutoFillOnPageLoad": { "message": "Automaattitäyttö sivun avautuessa (jos määritetty asetuksista)" @@ -1316,10 +1316,10 @@ "message": "Käytä oletusasetusta" }, "autoFillOnPageLoadYes": { - "message": "Automaattitäyttö sivun avautuessa" + "message": "Automaattitäytä sivun avautuessa" }, "autoFillOnPageLoadNo": { - "message": "Ei automaattitäyttöä sivun avautuessa" + "message": "Älä automaattitäytä sivun avautuessa" }, "commandOpenPopup": { "message": "Avaa holvin ponnahdusikkuna" @@ -1555,7 +1555,7 @@ } }, "editItemHeader": { - "message": "Muokkaa kohdetta $TYPE$", + "message": "Muokkaa: $TYPE$", "placeholders": { "type": { "content": "$1", @@ -2090,7 +2090,7 @@ "message": "Salasanasuojattu" }, "copyLink": { - "message": "Copy link" + "message": "Kopioi linkki" }, "copySendLink": { "message": "Kopioi Send-linkki", @@ -2684,7 +2684,7 @@ "message": "Tunnistelauseke" }, "fingerprintMatchInfo": { - "message": "Varmista, että holvisi on avattu ja tunnistelauseke täsmää toisella laitteella." + "message": "Varmista, että vahvistavan laitteen holvi on avattu ja että se näyttää saman tunnistelausekkeen." }, "resendNotification": { "message": "Lähetä ilmoitus uudelleen" @@ -2753,10 +2753,10 @@ "message": "Automaattitäytön asetukset" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Automaattitäyttö-pikakuvake" + "message": "Automaattitäytön pikanäppäin" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Muuta pikakuvaketta" + "message": "Muuta pikanäppäintä" }, "autofillShortcut": { "message": "Automaattitäytön pikanäppäin" @@ -2765,7 +2765,7 @@ "message": "Automaattisen täytön pikanäppäintä ei ole määritetty. Määritä se selaimen asetuksista." }, "autofillShortcutText": { - "message": "Automaattisen täytön pikanäppäin on $COMMAND$. Vaihda se selaimen asetuksista.", + "message": "Automaattisen täytön pikanäppäin on $COMMAND$. Muuta sitä selaimen asetuksista.", "placeholders": { "command": { "content": "$1", @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Näytä automaattitäytön ehdotukset avaamalla tilisi lukitus", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Avaa tilisi lukitus. Avautuu uudessa ikkunassa.", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Uusi kirjautumistieto", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Lisää holviin uusi kirjautumistieto. Avautuu uudessa ikkunassa.", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Uusi kortti", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Lisää holviin uusi korttitieto. Avautuu uudessa ikkunassa.", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Uusi henkilöllisyys", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Lisää holviin uusi henkilöllisyys. Avautuu uudessa ikkunassa.", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3470,19 +3470,19 @@ "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Muuta selaimesi automaattitäytön ja salasananhallinnan asetuksia.", + "message": "Muuta selaimesi automaattisen täytön ja salasanojen hallinnan asetuksia.", "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": "Voit tarkastella ja asettaa laajennusten pikakuvakkeita selaimesi asetuksissa.", + "message": "Voit tarkastella ja asettaa laajennusten pikavalintoja selaimesi asetuksissa.", "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": "Muuta selaimesi automaattitäytön ja salasananhallinnan asetuksia.", + "message": "Muuta selaimesi automaattisen täytön ja salasanojen hallinnan asetuksia.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "Voit tarkastella ja asettaa laajennusten pikakuvakkeita selaimesi asetuksissa.", + "message": "Voit tarkastella ja asettaa laajennusten pikavalintoja selaimesi asetuksissa.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "kortin numero päättyy", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 4c2111481f2..9e04e5aa2ea 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -3,27 +3,27 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "Bitwarden upravitelj lozinki", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "message": "Kod kuće, na poslu ili u pokretu, Bitwarden štiti sve tvoje lozinke, pristupne ključeve i osjetljive informacije", "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Prijavi se ili stvori novi račun za pristup svojem sigurnom trezoru." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Pozivnica prihvaćena" }, "createAccount": { "message": "Stvori račun" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Postavi jaku lozinku" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Dovrši stvaranje svog računa postavljanjem lozinke" }, "login": { "message": "Prijava" @@ -53,7 +53,7 @@ "message": "Podsjetnik glavne lozinke ti može pomoći da se prisjetiš svoje lozinke ako ju zaboraviš." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Podsjetnik ti možemo poslati ako zaboraviš svoju lozinku. Najviše $CURRENT$/$MAXIMUM$ znakova.", "placeholders": { "current": { "content": "$1", @@ -72,10 +72,10 @@ "message": "Podsjetnik glavne lozinke (neobavezno)" }, "joinOrganization": { - "message": "Join organization" + "message": "Pridruži se organizaciji" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Dovrši pridruživanje organizaciji postavljanjem glavne lozinke." }, "tab": { "message": "Kartica" @@ -198,25 +198,25 @@ "message": "Promjeni glavnu lozinku" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Nastavi na web aplikaciju?" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "Pronađi viđe značajki svojeg Bitwarden računa u web aplikaciji." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "Nastavi u centar za pomoć?" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "Za pomoć oko korištenja Bitwardena posjeti centar za pomoć." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "Nastaviti na trgovinu proširenja za preglednik?" }, "continueToBrowserExtensionStoreDesc": { - "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." + "message": "Želiš preporučiti Bitwarden drugima? Posjeti trgovinu proširenja svojeg preglednika i ostavi recenziju." }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Svoju lozinku možeš promijeniti u Bitwarden web aplikaciji." }, "fingerprintPhrase": { "message": "Jedinstvena fraza", @@ -233,43 +233,43 @@ "message": "Odjava" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "O Bitwardenu" }, "about": { "message": "O aplikaciji" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "Više od Bitwardena" }, "continueToBitwardenDotCom": { - "message": "Continue to bitwarden.com?" + "message": "Nastavi na bitwarden.com?" }, "bitwardenForBusiness": { - "message": "Bitwarden for Business" + "message": "Bitwarden za tvrtke" }, "bitwardenAuthenticator": { - "message": "Bitwarden Authenticator" + "message": "Bitwarden autentifikator" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website" + "message": "Bitwarden autentifikator omogućuje pohranu ključeva za autentifikaciju i generiranje TOTP kodova za dvostruku autentifikaciju. Saznaj više na web stranici bitwarden.com" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Bitwarden Upravitelj tajni" }, "continueToSecretsManagerPageDesc": { - "message": "Securely store, manage, and share developer secrets with Bitwarden Secrets Manager. Learn more on the bitwarden.com website." + "message": "Sigurno pohrani, upravljaj i dijeli programerske tajne s Bitwarden Secrets Managerom. Saznajte više na web stranici bitwarden.com." }, "passwordlessDotDev": { "message": "Passwordless.dev" }, "continueToPasswordlessDotDevPageDesc": { - "message": "Create smooth and secure login experiences free from traditional passwords with Passwordless.dev. Learn more on the bitwarden.com website." + "message": "Stvori laka i sigurna iskustva prijave bez tradicionalnih lozinki uz Passwordless.dev. Saznaj više na web stranici bitwarden.com." }, "freeBitwardenFamilies": { - "message": "Free Bitwarden Families" + "message": "Besplatan obiteljski Bitwarden" }, "freeBitwardenFamiliesPageDesc": { - "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." + "message": "Ispunjavaš uvjete za besplatni obiteljski Bitwarden. Iskoristi ovu ponudu u web aplikaciji već danas." }, "version": { "message": "Verzija" @@ -330,7 +330,7 @@ "message": "Automatski generiraj jake, jedinstvene lozinke." }, "bitWebVaultApp": { - "message": "Bitwarden web app" + "message": "Bitwarden web trezor" }, "importItems": { "message": "Uvoz stavki" @@ -418,13 +418,13 @@ "message": "Favorit" }, "unfavorite": { - "message": "Unfavorite" + "message": "Ukloni iz favorita" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Dodaj stavku u omiljene" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Stavka uklonjenja iz omiljenih" }, "notes": { "message": "Bilješke" @@ -448,7 +448,7 @@ "message": "Pokreni" }, "launchWebsite": { - "message": "Launch website" + "message": "Pokreni web stranicu" }, "website": { "message": "Web stranica" @@ -463,7 +463,7 @@ "message": "Ostalo" }, "unlockMethods": { - "message": "Unlock options" + "message": "Opcije otključavanja" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "Za promjenu vremena isteka trezora, odredi način otključavanja." @@ -472,10 +472,10 @@ "message": "Postavi način otključavanja u Postavkama" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "Istek sesije" }, "otherOptions": { - "message": "Other options" + "message": "Ostale postavke" }, "rateExtension": { "message": "Ocijeni proširenje" @@ -566,16 +566,16 @@ "message": "Sigurnost" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "Potvrdi glavnu lozinku" }, "masterPassword": { - "message": "Master password" + "message": "Glavna lozinka" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "Glavnu lozinku nije moguće oporaviti ako ju zaboraviš!" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "Podsjetnik glavne lozinke" }, "errorOccurred": { "message": "Došlo je do pogreške" @@ -609,10 +609,10 @@ "message": "Tvoj novi račun je kreiran! Sada se možeš prijaviti." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Prijava uspješna" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Možeš zatvoriti ovaj prozor" }, "masterPassSent": { "message": "Poslali smo e-poštu s podsjetnikom glavne lozinke." @@ -621,7 +621,7 @@ "message": "Potvrdni kôd je obavezan." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Autentifikacija je otkazana ili je trajala predugo. Molimo pokušaj ponovno." }, "invalidVerificationCode": { "message": "Nevažeći kôd za provjeru" @@ -646,16 +646,16 @@ "message": "Ključ autentifikatora je dodan" }, "totpCapture": { - "message": "Skenirajte QR kod autentifikatora s trenutne web stranice" + "message": "Skeniraj QR kôd autentifikatora s trenutne web stranice" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Učini dvostruku autentifikaciju besprijekornom" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden može pohraniti i ispuniti kodove za dvostruku autentifikaciju. Kopiraj i zalijepi ključ u ovo polje." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden može pohraniti i ispuniti kodove za dvostruku autentifikaciju. Odaberi ikonu kamere i označi QR kôd za provjeru autentičnosti ove web stranice ili kopiraj i zalijepi ključ u ovo polje." }, "copyTOTP": { "message": "Kopiraj ključ autentifikatora (TOTP)" @@ -664,25 +664,25 @@ "message": "Odjavljen" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Odjavljen/a si sa svog računa." }, "loginExpired": { "message": "Sesija je istekla." }, "logIn": { - "message": "Log in" + "message": "Prijavi se" }, "restartRegistration": { - "message": "Restart registration" + "message": "Ponovno pokreni registraciju" }, "expiredLink": { - "message": "Expired link" + "message": "Istekla poveznica" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Ponovno pokreni registraciju ili se pokušaj prijaviti." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Možda već imaš račun" }, "logOutConfirmation": { "message": "Sigurno se želiš odjaviti?" @@ -746,7 +746,7 @@ "message": "Novi URI" }, "addDomain": { - "message": "Add domain", + "message": "Dodaj domenu", "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." }, "addedItem": { @@ -790,7 +790,7 @@ "message": "Upitaj za dodavanje prijave" }, "vaultSaveOptionsTitle": { - "message": "Save to vault options" + "message": "Mogućnosti spremanja u trezor" }, "addLoginNotificationDesc": { "message": "Upit za dodavanje prijave pojavljuje se kada se otkrije prva prijava na neko web mjesto. Bitwarden će te pitatati želiš li uneseno korisničko ime i lozinku spremiti u svoj trezor." @@ -799,7 +799,7 @@ "message": "Pitaj za dodavanje stavke ako nije pronađena u tvojem trezoru. Primjenjuje se na sve prijavljene račune." }, "showCardsInVaultView": { - "message": "Show cards as Autofill suggestions on Vault view" + "message": "Prikaži kartice kao prijedloge za auto-ispunu u prikazu trezora" }, "showCardsCurrentTab": { "message": "Prikaži platne kartice" @@ -808,7 +808,7 @@ "message": "Prikazuj platne kartice za jednostavnu auto-ispunu." }, "showIdentitiesInVaultView": { - "message": "Show identifies as Autofill suggestions on Vault view" + "message": "Prikaži identitete kao prijedloge za auto-ispunu u prikazu trezora" }, "showIdentitiesCurrentTab": { "message": "Prikaži identitete" @@ -858,7 +858,7 @@ "message": "Otključaj" }, "additionalOptions": { - "message": "Additional options" + "message": "Dodatne mogućnosti" }, "enableContextMenuItem": { "message": "Prikaži opcije kotekstualnog izbornika" @@ -898,7 +898,7 @@ "description": "'Solarized' is a noun and the name of a color scheme. It should not be translated." }, "exportFrom": { - "message": "Export from" + "message": "Izvezi iz" }, "exportVault": { "message": "Izvezi trezor" @@ -907,28 +907,28 @@ "message": "Format datoteke" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "Ova izvozna datoteka biti će zaštićena lozinkom bez koje ju neće biti moguće dešifrirati." }, "filePassword": { - "message": "File password" + "message": "Lozinka datoteke" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "message": "Ova će se lozinka koristiti za izvoz i uvoz ove datoteke" }, "accountRestrictedOptionDescription": { - "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account." + "message": "Upotrijebi svoj ključ za šifriranje računa, izveden iz korisničkog imena i glavne lozinke za šifriranje izvoza i ograničavanje uvoza samo na trenutni Bitwarden račun." }, "passwordProtectedOptionDescription": { - "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." + "message": "Bitwarden omogućuje dijeljenje trezora s drugima pomoću organizacijskog računa. Za više informacija posjeti bitwarden. com." }, "exportTypeHeading": { - "message": "Export type" + "message": "Tip izvoza" }, "accountRestricted": { - "message": "Account restricted" + "message": "Račun ograničen" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "Lozinka se ne podudara." }, "warning": { "message": "UPOZORENJE", @@ -953,7 +953,7 @@ "message": "Dijeljeno" }, "bitwardenForBusinessPageDesc": { - "message": "Bitwarden for Business allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website." + "message": "Bitwarden for Business omogućuje dijeljenje stavki trezora s drugima koristeći organizacije. Za više informacija posjeti bitwarden.com." }, "moveToOrganization": { "message": "Premjesti u organizaciju" @@ -1167,17 +1167,17 @@ "message": "Autentifikatorska aplikacija" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Unesi kôd generiran autentifikatorskom aplikacijom kao npr. Bitwarden Authenticatorom.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "Yubico OTP sigurnosni ključ" }, "yubiKeyDesc": { "message": "Koristi YubiKey za pristup svojem računu. Radi s YubiKey 4, 4 Nano, 4C i NEO uređajima." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Unesi kôd generiran Duo Securityjem.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1194,7 +1194,7 @@ "message": "E-pošta" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "Unesi kôd poslan e-poštom." }, "selfHostedEnvironment": { "message": "Vlastito hosting okruženje" @@ -1203,13 +1203,13 @@ "message": "Navedi osnovni URL svoje lokalno smještene Bitwarden instalacije." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Navedi osnovni URL svoje lokalne Bitwarden instalacije, npr.: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Kao naprednu postavku, možeš odrediti osnovni URL svake usluge zasebno." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Moraš dodati ili osnovni URL poslužitelja ili barem jedno prilagođeno okruženje." }, "customEnvironment": { "message": "Prilagođeno okruženje" @@ -1243,19 +1243,19 @@ "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Autofill suggestions" + "message": "Prijedlozi auto-ispune" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "Prikaži prijedloge auto-ispune na poljima obrazaca" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "Prikaži prijedloge kada je odabrana ikona" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "Primjenjuje se na sve prijavljene račune." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Isključite postavke upravitelja zaporki ugrađene u preglednik kako biste izbjegli sukobe." + "message": "Isključi preglednikov upravitelj lozinki kako bi izbjegli sukobe." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Uredi postavke preglednika." @@ -1273,7 +1273,7 @@ "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "Auto-ispuna kod učitavanja stranice" }, "enableAutoFillOnPageLoad": { "message": "Auto-ispuna kod učitavanja" @@ -1282,7 +1282,7 @@ "message": "Nakon učitavanja web stranice, ako je otkriven obrazac za prijavu, auto-ispuni." }, "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "message": "$OPENTAG$Upozorenje:$CLOSETAG$ Ugrožene ili nepouzdane web stranice mogu iskoristiti auto-ispunu prilikom učitavanja stranice.", "placeholders": { "openTag": { "content": "$1", @@ -1298,7 +1298,7 @@ "message": "Ugrožene ili nepouzdane web stranice mogu iskoristiti auto-ispunu prilikom učitavanja stranice." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "Saznaj više o rizicima" }, "learnMoreAboutAutofill": { "message": "Saznaj više o auto-ispuni" @@ -1307,7 +1307,7 @@ "message": "Zadana postvaka Auto-ispune za prijave" }, "defaultAutoFillOnPageLoadDesc": { - "message": "Nakon omogućavanja auto-ispune kod učitavanja stranice, moguće je uključiti/isključiti ovu značajku za svaku pojedinu prijavu. Ovo je zadana postavka za prijave koje nisu pojedinčano određene." + "message": "Auto-ispunu kod učitavanju stranice je moguće uključiti/isključiti za svaku pojedinu prijavu unutar uređivanja stavke." }, "itemAutoFillOnPageLoad": { "message": "Auto-ispuna kod učitavanja stranice (ako je uključeno u Postavkama)" @@ -1316,10 +1316,10 @@ "message": "Koristi zadane postavke" }, "autoFillOnPageLoadYes": { - "message": "Auto-ispuna kod učitavanja" + "message": "Auto-ispuna kod učitavanja stranice" }, "autoFillOnPageLoadNo": { - "message": "Ne koristi Auto-ispunu kod učitavanja" + "message": "Ne koristi auto-ispunu kod učitavanja stranice" }, "commandOpenPopup": { "message": "Otvori iskočni prozor trezora" @@ -1361,7 +1361,7 @@ "message": "Boolean" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Potvrdni okvir" }, "cfTypeLinked": { "message": "Povezano", @@ -1546,7 +1546,7 @@ "message": "Identitet" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "Novi $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1555,7 +1555,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Uredi $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1564,7 +1564,7 @@ } }, "viewItemHeader": { - "message": "View $TYPE$", + "message": "Pogledaj $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1582,7 +1582,7 @@ "message": "Zbirke" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ zbirki", "placeholders": { "count": { "content": "$1", @@ -1752,7 +1752,7 @@ "message": "Nerispravan PIN." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "Previše netočnih pokušaja unosa PIN-a. Odjava..." }, "unlockWithBiometrics": { "message": "Otključaj biometrijom" @@ -1808,7 +1808,7 @@ "message": "Stavka vraćena" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "Već imaš račun?" }, "vaultTimeoutLogOutConfirmation": { "message": "Odjava će ukloniti pristup tvom trezoru i zahtijevati mrežnu potvrdu identiteta nakon isteka vremenske neaktivnosti. Sigurno želiš koristiti ovu postavku?" @@ -1820,7 +1820,7 @@ "message": "Auto-ispuni i spremi" }, "fillAndSave": { - "message": "Fill and save" + "message": "Ispuni i spremi" }, "autoFillSuccessAndSavedUri": { "message": "Auto-ispunjena stavka i spremanje URI" @@ -1901,19 +1901,19 @@ "message": "Tvoja nova glavna lozinka ne ispunjava zahtjeve." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Primaj e-poštom od Bitwardena savjete, najave i mogućnosti istraživanja." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Poništi pretplatu" }, "atAnyTime": { - "message": "at any time." + "message": "bilo kada." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Ako nastaviš, slažeš se s" }, "and": { - "message": "and" + "message": "i" }, "acceptPolicies": { "message": "Označavanjem ove kućice slažete se sa sljedećim:" @@ -1934,10 +1934,10 @@ "message": "U redu" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Pogreška osvježavanja tokena pristupa" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Nije pronađen token za osvježavanje ili API ključevi. Pokušaj se odjaviti i ponovno prijaviti." }, "desktopSyncVerificationTitle": { "message": "Potvrda desktop sinkronizacije" @@ -1988,10 +1988,10 @@ "message": "Biometrija preglednika nije podržana na ovom uređaju." }, "biometricsNotUnlockedTitle": { - "message": "User locked or logged out" + "message": "Korisnik zaključan ili odjavljen" }, "biometricsNotUnlockedDesc": { - "message": "Please unlock this user in the desktop application and try again." + "message": "Otključaj ovog korisnika u desktop aplikaciji i pokušaj ponovno." }, "biometricsFailedTitle": { "message": "Biometrija neuspješna" @@ -2021,7 +2021,7 @@ "message": "Organizacijsko pravilo onemogućuje uvoz stavki u tvoj osobni trezor." }, "domainsTitle": { - "message": "Domains", + "message": "Domene", "description": "A category title describing the concept of web domains" }, "excludedDomains": { @@ -2034,7 +2034,7 @@ "message": "Bitwarden neće tražiti spremanje podataka za prijavu za ove domene za sve prijavljene račune. Moraš osvježiti stranicu kako bi promjene stupile na snagu." }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "Web stranica $number$ (URI)", "placeholders": { "number": { "content": "$1", @@ -2052,7 +2052,7 @@ } }, "excludedDomainsSavedSuccess": { - "message": "Excluded domain changes saved" + "message": "Spremljene promjene izuzete domene" }, "send": { "message": "Send", @@ -2090,7 +2090,7 @@ "message": "Zaštićeno lozinkom" }, "copyLink": { - "message": "Copy link" + "message": "Kopiraj vezu" }, "copySendLink": { "message": "Kopiraj vezu na Send", @@ -2285,7 +2285,7 @@ "message": "Potrebna je potvrda e-pošte" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "e-pošta potvrđena" }, "emailVerificationRequiredDesc": { "message": "Moraš ovjeriti svoju e-poštu u mrežnom trezoru za koritšenje ove značajke." @@ -2312,7 +2312,7 @@ "message": "Odaberi mapu..." }, "noFoldersFound": { - "message": "No folders found", + "message": "Nema pronađenih mapa", "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { @@ -2324,7 +2324,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { - "message": "Verification required", + "message": "Potrebna je potvrda", "description": "Default title for the user verification dialog." }, "hours": { @@ -2430,10 +2430,10 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "Izvoz organizacijskog trezora" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "Izvest će se samo organizacijski trezor povezan s $ORGANIZATION$. Stavke iz osobnih trezora i stavke iz drugih organizacija neće biti uključene.", "placeholders": { "organization": { "content": "$1", @@ -2491,7 +2491,7 @@ "message": "Generiraj pseudonim e-pošte s vanjskom uslugom prosljeđivanja." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "$SERVICENAME$ greška: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -2505,11 +2505,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Generirao Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Generirao Bitwarden", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -2519,7 +2519,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Nevažeći $SERVICENAME$ API token", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2529,7 +2529,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Nevažeći $SERVICENAME$ API token: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2543,7 +2543,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "Nije moguće dobiti $SERVICENAME$ maskirani ID računa e-pošte.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2553,7 +2553,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Nevažeća $SERVICENAME$ domena.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -2563,7 +2563,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Nevažeći $SERVICENAME$ URL.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -2573,7 +2573,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Nepoznata $SERVICENAME$ greška.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -2583,7 +2583,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "Nepoznati prosljeditelj: '$SERVICENAME$.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -2753,10 +2753,10 @@ "message": "Postavke auto-ispune" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Prečac auto-ispune" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "Promijeni prečac" }, "autofillShortcut": { "message": "Tipkovnički precač auto-ispune" @@ -2810,25 +2810,25 @@ "message": "Potreban je identifikator organizacije." }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Stvaranje računa na" }, "checkYourEmail": { - "message": "Check your email" + "message": "Provjeri svoju e-poštu" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Slijedi vezu u e-pošti poslanoj na" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "za nastavak stvaranja tvojeg računa." }, "noEmail": { - "message": "No email?" + "message": "Nema e-pošte?" }, "goBack": { - "message": "Go back" + "message": "Nazad" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "na uređivanje svoje adrese e-pošte." }, "eu": { "message": "EU", @@ -2868,11 +2868,11 @@ "message": "Uređaj pouzdan" }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "Nema aktivnih Sendova", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendsNoItemsMessage": { - "message": "Use Send to securely share encrypted information with anyone.", + "message": "Koristi Send za sigurno slanje šifriranih podataka bilo kome.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "inputRequired": { @@ -2980,11 +2980,11 @@ "description": "Toggling an expand/collapse state." }, "filelessImport": { - "message": "Uvesti svoje podatke u Bitwarden?", + "message": "Uvezi svoje podatke u Bitwarden?", "description": "Default notification title for triggering a fileless import." }, "lpFilelessImport": { - "message": "Zaštititi svoje LastPass podatke i uvesti ih u Bitwarden?", + "message": "Zaštititi svoje LastPass podatke i uvezi ih u Bitwarden?", "description": "LastPass specific notification title for triggering a fileless import." }, "lpCancelFilelessImport": { @@ -2996,15 +2996,15 @@ "description": "Notification button text for starting a fileless import." }, "importing": { - "message": "Uvoženje...", + "message": "Uvoz...", "description": "Notification message for when an import is in progress." }, "dataSuccessfullyImported": { - "message": "Podaci su uspješno uvezeni!", + "message": "Uvoz podataka u trezor uspješan!", "description": "Notification message for when an import has completed successfully." }, "dataImportFailed": { - "message": "Greška pri uvozu. Provjerite konzolu za detalje.", + "message": "Greška pri uvozu. Provjeri konzolu za detalje.", "description": "Notification message for when an import has failed." }, "importNetworkError": { @@ -3027,10 +3027,10 @@ "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "U/Isključi bočnu navigaciju" }, "skipToContent": { - "message": "Skoči na sadržaj" + "message": "Preskoči na sadržaj" }, "bitwardenOverlayButton": { "message": "Tipka izbornika Bitwarden auto-ispune", @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Otključaj račun za prikaz prijedloga auto-ispuna", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Otključaj račun; otvara se u novom prozoru", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Nova prijava", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Dodaj novu stavku prijave u trezor; otvara se u novom prozoru", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Nova kartica", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Dodaj novu stavku kartice u trezor; otvara se u novom prozoru", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Novi identitet", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Dodaj novu stavku identiteta u trezor; otvara se u novom prozoru", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3143,40 +3143,40 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Pokušaj ponovno" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Za ovu radnju potrebna je potvrda. Postavi PIN za nastavak." }, "setPin": { - "message": "Set PIN" + "message": "Postavi PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Potvrdi biometrijom" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Čekanje potvrde" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Nije moguće dovršiti biometriju." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Koristi drugi način?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Koristi glavnu lozinku" }, "usePin": { - "message": "Use PIN" + "message": "Koristi PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Koristi biometriju" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "Unesi kôd za potvrdu primljen e-poštom." }, "resendCode": { - "message": "Resend code" + "message": "Ponovno pošalji kod" }, "total": { "message": "Ukupno" @@ -3191,22 +3191,22 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Greška pri povezivanju s uslugom Duo. Koristi drugu metodu prijave s dvostrukom autentifikacijom ili kontaktiraj Duo za pomoć." }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Pokreni Duo i slijedi korake za dovršetak prijave." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Za tvoj račun je potrebna Duo dvostruka autentifikacija." }, "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." + "message": "Otvori proširenje za dovršetak prijave." }, "popoutExtension": { - "message": "Popout extension" + "message": "Otvori proširenje" }, "launchDuo": { - "message": "Launch Duo" + "message": "Pokreni Duo" }, "importFormatError": { "message": "Podaci nisu ispravno formatirani. Provjeri uvoznu datoteku i pokušaj ponovno." @@ -3221,7 +3221,7 @@ "message": "Nesipravna lozinka datoteke. Unesi lozinku izvozne datoteke." }, "destination": { - "message": "Destination" + "message": "Odredište" }, "learnAboutImportOptions": { "message": "Više o mogućnostima uvoza" @@ -3280,7 +3280,7 @@ "message": "Potvrdi lozinku datoteke" }, "exportSuccess": { - "message": "Vault data exported" + "message": "Podaci iz trezora su izvezeni" }, "typePasskey": { "message": "Pristupni ključ" @@ -3343,13 +3343,13 @@ "message": "Neispravno korisničko ime ili lozinka" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Neispravna lozinka" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Neispravan kôd" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "Neispravan PIN" }, "multifactorAuthenticationFailed": { "message": "Multifaktorska autentifikacija nije uspjela" @@ -3373,7 +3373,7 @@ "message": "Odobri svoj zahtjev za prijavu u svojoj aplikaciji za autentifikaciju ili unesi jednokratni kôd." }, "passcode": { - "message": "Šifra" + "message": "Jednokratni kôd" }, "lastPassMasterPassword": { "message": "LastPass glavna lozinka" @@ -3422,25 +3422,25 @@ "message": "Dostupni računi" }, "accountLimitReached": { - "message": "Dosegnuto je ograničenje računa. Odjavite se s računa da biste dodali drugi." + "message": "Dosegnuto je ograničenje računa. Odjavi se s računa za dodavanje sljedećeg." }, "active": { - "message": "Aktivan" + "message": "aktivan" }, "locked": { - "message": "Zaključan" + "message": "zaključan" }, "unlocked": { - "message": "Otključan" + "message": "otključan" }, "server": { - "message": "Poslužitelj" + "message": "poslužitelj" }, "hostedAt": { "message": "domaćin na" }, "useDeviceOrHardwareKey": { - "message": "Koristite svoj uređaj ili hardverski ključ" + "message": "Koristi svoj uređaj ili hardverski ključ" }, "justOnce": { "message": "Samo jednom" @@ -3449,7 +3449,7 @@ "message": "Uvijek za ovu stranicu" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ dodano u izuzete domene.", + "message": "$DOMAIN$ dodana u izuzete domene.", "placeholders": { "domain": { "content": "$1", @@ -3458,95 +3458,95 @@ } }, "commonImportFormats": { - "message": "Common formats", + "message": "Uobičajeni oblici", "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "Nastavi na postavke preglednika?", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "Nastavi u centar za pomoć?", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "Promijeni postavke auto-ispune i upravljanja lozinkama preglednika.", "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": "You can view and set extension shortcuts in your browser's settings.", + "message": "Možeš vidjeti i postaviti prečace proširenja u postavkama preglednika.", "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": "Change your browser's autofill and password management settings.", + "message": "Promijeni postavke auto-ispune i upravljanja lozinkama u preglednika.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "Možeš vidjeti i postaviti prečace proširenja u postavkama preglednika.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { - "message": "Make Bitwarden your default password manager?", + "message": "Postavi Bitwarden kao zadani upravitelj lozinki?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", + "message": "Ostavljanje ove postavke isključenom može uzrokovati sukob između prijedloga za auto-ispunu Bitwardena i tvojeg preglednika.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { - "message": "Make Bitwarden your default password manager", + "message": "Postavi Bitwarden kao zadani upravitelj lozinki", "description": "Label for the setting that allows overriding the default browser autofill settings" }, "privacyPermissionAdditionNotGrantedTitle": { - "message": "Unable to set Bitwarden as the default password manager", + "message": "Nije moguće postaviti Bitwarden kao zadani upravitelj lozinki", "description": "Title for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "privacyPermissionAdditionNotGrantedDescription": { - "message": "You must grant browser privacy permissions to Bitwarden to set it as the default password manager.", + "message": "Za postavljanje Bitwardena kao zadanog upravitelja lozinki moraš pregledniku dati dopuštenje privatnosti.", "description": "Description for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "makeDefault": { - "message": "Make default", + "message": "Postavi kao zadano", "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "Vjerodajnice uspješno spremljene!", "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "Vjerodajnice uspješno ažurirane!", "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "Greška pri spremanju vjerodajnica. Za detalje pogledaj konzolu.", "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "Uspješno" }, "removePasskey": { - "message": "Remove passkey" + "message": "Ukloni pristupni ključ" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Pristupni ključ uklonjen" }, "autofillSuggestions": { - "message": "Auto-fill suggestions" + "message": "Prijedlozi auto-ispune" }, "autofillSuggestionsTip": { - "message": "Save a login item for this site to auto-fill" + "message": "Spremi u auto-ispunu stavku prijave za ovu stranicu" }, "yourVaultIsEmpty": { - "message": "Your vault is empty" + "message": "Tvoj trezor je prazan" }, "noItemsMatchSearch": { - "message": "No items match your search" + "message": "Nema stavki podudarnih s pretragom" }, "clearFiltersOrTryAnother": { - "message": "Clear filters or try another search term" + "message": "Očisti filtre ili pokušaj s drugačijom pretragom" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Kopiraj informacije - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -3556,7 +3556,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Kopiraj bilješku - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -3566,7 +3566,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Više mogućnosti, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3576,7 +3576,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Više mogućnosti - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3586,7 +3586,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Pogledaj stavku - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -3596,7 +3596,7 @@ } }, "autofillTitle": { - "message": "Auto-fill - $ITEMNAME$", + "message": "Auto-ispuna - $ITEMNAME$", "description": "Title for a button that auto-fills a login item.", "placeholders": { "itemname": { @@ -3606,40 +3606,40 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "Nema vrijednosti za kopiranje" }, "assignToCollections": { - "message": "Assign to collections" + "message": "Dodijeli zbirkama" }, "copyEmail": { - "message": "Copy email" + "message": "Kopiraj e-poštu" }, "copyPhone": { - "message": "Copy phone" + "message": "Kopiraj telefon" }, "copyAddress": { - "message": "Copy address" + "message": "Kopiraj adresu" }, "adminConsole": { - "message": "Admin Console" + "message": "Konzola administratora" }, "accountSecurity": { - "message": "Account security" + "message": "Sigurnost računa" }, "notifications": { - "message": "Notifications" + "message": "Obavijesti" }, "appearance": { - "message": "Appearance" + "message": "Izgled" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Greška pri dodjeljivanju ciljne zbirke." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Greška pri dodjeljivanju ciljne mape." }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Pogledaj stavku u $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -3649,7 +3649,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Natrag na $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -3659,10 +3659,10 @@ } }, "new": { - "message": "New" + "message": "Novo" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Ukloni $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -3672,16 +3672,16 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "Stavke bez mape" }, "itemDetails": { - "message": "Item details" + "message": "Detalji stavke" }, "itemName": { - "message": "Item name" + "message": "Naziv stavke" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "S dopuštenjima samo za prikaz ne možeš ukloniti zbirke: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -3690,47 +3690,47 @@ } }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "Organizacija je deaktivirana" }, "owner": { - "message": "Owner" + "message": "Vlasnik" }, "selfOwnershipLabel": { - "message": "You", + "message": "Ti", "description": "Used as a label to indicate that the user is the owner of an item." }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "Ne može se pristupiti stavkama u deaktiviranoj Organizaciji. Kontaktiraj vlasnika Organizacije za pomoć." }, "additionalInformation": { - "message": "Additional information" + "message": "Dodatne informacije" }, "itemHistory": { - "message": "Item history" + "message": "Povijest stavke" }, "lastEdited": { - "message": "Last edited" + "message": "Zadnje uređeno" }, "ownerYou": { - "message": "Owner: You" + "message": "Vlasnik: Ti" }, "linked": { - "message": "Linked" + "message": "Povezano" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Kopiranje uspješno" }, "upload": { - "message": "Upload" + "message": "Prijenos" }, "addAttachment": { - "message": "Add attachment" + "message": "Dodaj privitak" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "Najveća veličina datoteke je 500 MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "Izbriši privitak", "placeholders": { "name": { "content": "$1", @@ -3739,7 +3739,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "Preuzmi $NAME$", "placeholders": { "name": { "content": "$1", @@ -3748,28 +3748,28 @@ } }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "Sigurno želiš trajno obrisati ovaj privitak?" }, "premium": { "message": "Premium" }, "freeOrgsCannotUseAttachments": { - "message": "Free organizations cannot use attachments" + "message": "Besplatne organizacije ne mogu koristiti privitke" }, "filters": { - "message": "Filters" + "message": "Filtri" }, "personalDetails": { - "message": "Personal details" + "message": "Osobni podaci" }, "identification": { - "message": "Identification" + "message": "Identifikacija" }, "contactInfo": { - "message": "Contact info" + "message": "Kontakt podaci" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "Preuzmi - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -3778,20 +3778,20 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "broj kartice završava na", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { - "message": "Login credentials" + "message": "Vjerodajnice za prijavu" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Kôd za provjeru" }, "cardDetails": { - "message": "Card details" + "message": "Detalji kartice" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "$BRAND$ detalji", "placeholders": { "brand": { "content": "$1", @@ -3800,25 +3800,25 @@ } }, "addAccount": { - "message": "Add account" + "message": "Dodaj račun" }, "loading": { - "message": "Loading" + "message": "Učitavanje" }, "data": { - "message": "Data" + "message": "Podaci" }, "assign": { - "message": "Assign" + "message": "Dodijeli" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Samo članovi organizacije s pristupom ovim zbirkama će moći vidjeti stavku." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Samo članovi organizacije s pristupom ovim zbirkama će moći vidjeti stavke." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Odabrano je $TOTAL_COUNT$ stavki. Nije moguće ažurirati $READONLY_COUNT$ stavki jer nemaš dopuštenje za uređivanje.", "placeholders": { "total_count": { "content": "$1", @@ -3830,37 +3830,37 @@ } }, "addField": { - "message": "Add field" + "message": "Dodaj polje" }, "add": { - "message": "Add" + "message": "Dodaj" }, "fieldType": { - "message": "Field type" + "message": "Vrsta polja" }, "fieldLabel": { - "message": "Field label" + "message": "Oznaka polja" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Koristi tekstualna polja za podatke poput sigurnosnih pitanja" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Koristi skrivena polja za osjetljive podatke poput lozinke" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to auto-fill a form's checkbox, like a remember email" + "message": "Koristi potvrdne okvire ako ih želiš automatski uključiti u obrascu, npr. zapamti adresu e-pošte" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing auto-fill issues for a specific website." + "message": "Koristi povezano polje kada imaš problema s auto-ispunom za određenu web stranicu." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "Unesi html id polja, naziv, aria-label ili rezervirano mjesto." }, "editField": { - "message": "Edit field" + "message": "Uredi polje" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "Uredi $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3869,7 +3869,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "Obriši $LABEL$", "placeholders": { "label": { "content": "$1", @@ -3878,7 +3878,7 @@ } }, "fieldAdded": { - "message": "$LABEL$ added", + "message": "$LABEL$ dodana", "placeholders": { "label": { "content": "$1", @@ -3887,7 +3887,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "Ponovno poredaj $LABEL$. Koristi tipke sa strelicom za pomicanje stavke gore ili dolje.", "placeholders": { "label": { "content": "$1", @@ -3896,7 +3896,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ pomaknut gore, pozicija $INDEX$ od $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -3913,13 +3913,13 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Odaberi zbirke za dodjelu" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 stavka će biti trajno prenesena u odabranu organizaciju. Više nećeš posjedovati ovu stavku." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ stavke/i će biti trajno prenesene u odabranu organizaciju. Više nećeš posjedovati ove stavke.", "placeholders": { "personal_items_count": { "content": "$1", @@ -3928,7 +3928,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 stavka će biti trajno prenesena u $ORG$. Više nećeš posjedovati ovu stavku.", "placeholders": { "org": { "content": "$1", @@ -3937,7 +3937,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ stavke/i će biti trajno prenesene u $ORG$. Više nećeš posjedovati ove stavke.", "placeholders": { "personal_items_count": { "content": "$1", @@ -3950,13 +3950,13 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Zbirke uspješno dodijeljene" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Ništa nije odabrano." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Odabrane stavke premještene u $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3965,7 +3965,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Stavke premještene u $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3974,7 +3974,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Stavka premještena u $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -3983,7 +3983,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ pomaknuto dolje, pozicija $INDEX$ od$LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4000,6 +4000,6 @@ } }, "itemLocation": { - "message": "Item Location" + "message": "Lokacija stavke" } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index c9ad9bb0b1a..d5edc6d7ac8 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -2090,7 +2090,7 @@ "message": "Jelszóval védett" }, "copyLink": { - "message": "Copy link" + "message": "Hivatkozás másolása" }, "copySendLink": { "message": "Send hivatkozás másolása", @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Oldjuk fel a fiók zárolását az automatikus kitöltési javaslatok megtekintéséhez.", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Oldjuk fel a fiók zárolását, új ablakban nyílik meg.", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Új bejelentkezés", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Új széf bejelentkezési elem hozzáadása, új ablakban nyílik meg.", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Új kártya", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Új széf kártyaelem hozzáadása, új ablakban nyílik meg.", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Új személyazonosság", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Új széf személyazonosság elem hozzáadása, új ablakban nyílik meg.", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "kártyaszám végződés:", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index da162d03bfc..17f62a2c599 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -14,7 +14,7 @@ "message": "安全なデータ保管庫へアクセスするためにログインまたはアカウントを作成してください。" }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "招待が承認されました" }, "createAccount": { "message": "アカウントの作成" @@ -72,10 +72,10 @@ "message": "マスターパスワードのヒント (省略可能)" }, "joinOrganization": { - "message": "Join organization" + "message": "組織に参加" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "マスターパスワードを設定して、この組織への参加を完了します。" }, "tab": { "message": "タブ" @@ -2090,7 +2090,7 @@ "message": "パスワード保護あり" }, "copyLink": { - "message": "Copy link" + "message": "リンクをコピー" }, "copySendLink": { "message": "Send リンクをコピー", @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "自動入力候補を表示するにはアカウントのロックを解除してください", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "アカウントのロックを解除し、新しいウィンドウで開く", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "新規ログイン", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "新しい保管庫のログインアイテムを追加し、新しいウィンドウで開く", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "新しいカード", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "新しい保管庫のカードアイテムを追加し、新しいウィンドウで開く", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "新しい ID", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "新しい保管庫 ID アイテムを追加し、新しいウィンドウで開く", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "カード番号の末尾", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 10cf754ab15..3b0219cf44a 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -14,7 +14,7 @@ "message": "Jāpiesakās vai jāizveido jauns konts, lai piekļūtu drošajai glabātavai." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Uzaicinājums apstiprināts" }, "createAccount": { "message": "Izveidot kontu" @@ -72,10 +72,10 @@ "message": "Galvenās paroles norāde (nav nepieciešama)" }, "joinOrganization": { - "message": "Join organization" + "message": "Pievienoties apvienībai" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Pabeigt pievienošanos šai apvienībai ar galvenās paroles iestatīšanu." }, "tab": { "message": "Cilne" @@ -2090,7 +2090,7 @@ "message": "Aizsargāts ar paroli" }, "copyLink": { - "message": "Copy link" + "message": "Ievietot saiti starpliktuvē" }, "copySendLink": { "message": "Ievietot Send saiti starpliktuvē", @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Jāatslēdz savs konts, lai apskatītu automātiskās aizpildes ieteikumus", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Atslēgt savu kontu, tiks atvērts jaunā logā", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Jauns pieteikšanās vienums", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Pievienot jaunu glabātavas pieteikšanās vienumu, tiks atvērts jaunā logā", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Jauna karte", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Pievienot jaunu glabātavas kartes vienumu, tiks atvērts jaunā logā", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Jauna identitāte", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Pievienot jaunu glabātavas identitātes vienumu, tiks atvērts jaunā logā", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "kartes numurs beidzas ar", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 09c309cafd3..d1f419b3b44 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -2090,7 +2090,7 @@ "message": "Chránené heslom" }, "copyLink": { - "message": "Copy link" + "message": "Kopírovať odkaz" }, "copySendLink": { "message": "Kopírovať odkaz na Send", @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Odomknúť konto v novom okne", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3085,7 +3085,7 @@ "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Pridať do trezora nové prihlásenie. Otvorí sa v novom okne", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { @@ -3093,15 +3093,15 @@ "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Pridať do trezora novú kartu. Otvorí sa v novom okne", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Nová identita", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Pridať do trezora novú identitu. Otvorí sa v novom okne", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3221,7 +3221,7 @@ "message": "Neplatné heslo súboru, použite heslo, ktoré ste zadali pri vytváraní exportného súboru." }, "destination": { - "message": "Destination" + "message": "Cieľ" }, "learnAboutImportOptions": { "message": "Zistiť viac o možnostiach importu" @@ -3806,7 +3806,7 @@ "message": "Načíta sa" }, "data": { - "message": "Data" + "message": "Údaje" }, "assign": { "message": "Priradiť" diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 67b478550ea..af0614b29f0 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -1282,7 +1282,7 @@ "message": "Якщо виявлено форму входу, автоматично заповнювати її під час завантаження вебсторінки." }, "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", + "message": "$OPENTAG$Обережно!$CLOSETAG$ Скомпрометовані або ненадійні вебсайти можуть використати функцію автозаповнення під час завантаження сторінки для завдання шкоди.", "placeholders": { "openTag": { "content": "$1", @@ -1298,7 +1298,7 @@ "message": "Скомпрометовані або ненадійні вебсайти можуть використати функцію автозаповнення під час завантаження сторінки для завдання шкоди." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "Докладніше про ризики" }, "learnMoreAboutAutofill": { "message": "Докладніше про автозаповнення" @@ -2090,7 +2090,7 @@ "message": "Захищено паролем" }, "copyLink": { - "message": "Copy link" + "message": "Копіювати посилання" }, "copySendLink": { "message": "Копіювати посилання відправлення", @@ -2753,10 +2753,10 @@ "message": "Налаштування автозаповнення" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Комбінація клавіш автозаповнення" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "Змінити комбінацію клавіш" }, "autofillShortcut": { "message": "Комбінації клавіш автозаповнення" @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Розблокуйте обліковий запис, щоб переглянути пропозиції автозаповнення", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Розблокування облікового запису – відкриється нове вікно", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Новий запис", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Додавання нового запису для входу – відкриється нове вікно", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Нова картка", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Додавання нової картки – відкриється нове вікно", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Особисті дані", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Додавання нового запису для особистих даних – відкриється нове вікно", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3221,7 +3221,7 @@ "message": "Неправильний пароль файлу. Використайте пароль, який ви вводили під час створення експортованого файлу." }, "destination": { - "message": "Destination" + "message": "Призначення" }, "learnAboutImportOptions": { "message": "Дізнайтеся про параметри імпорту" @@ -3462,27 +3462,27 @@ "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "Відкрити налаштування браузера?", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "Відкрити довідковий центр?", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "Змінити параметри автозаповнення та керування паролями браузера.", "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": "You can view and set extension shortcuts in your browser's settings.", + "message": "Ви можете переглядати й керувати комбінаціями клавіш для розширень у налаштуваннях браузера.", "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": "Change your browser's autofill and password management settings.", + "message": "Змінити параметри автозаповнення та керування паролями браузера.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "Ви можете переглядати й керувати комбінаціями клавіш для розширень у налаштуваннях браузера.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "номер картки закінчується на", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { @@ -3806,16 +3806,16 @@ "message": "Завантаження" }, "data": { - "message": "Data" + "message": "Дані" }, "assign": { "message": "Призначити" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Лише учасники організації з доступом до цих збірок зможуть переглядати запис." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Лише учасники організації з доступом до цих збірок зможуть переглядати записи." }, "bulkCollectionAssignmentWarning": { "message": "Ви вибрали $TOTAL_COUNT$ записів. Ви не можете оновити $READONLY_COUNT$ записів, тому що у вас немає дозволу на редагування.", diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 4f649589d0f..c34156f0d12 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -14,7 +14,7 @@ "message": "登录或者创建一个账户来访问您的安全密码库。" }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "邀请已接受" }, "createAccount": { "message": "创建账户" @@ -72,10 +72,10 @@ "message": "主密码提示(可选)" }, "joinOrganization": { - "message": "Join organization" + "message": "加入组织" }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "通过设置主密码完成加入此组织。" }, "tab": { "message": "标签页" @@ -808,7 +808,7 @@ "message": "在标签页上列出支付卡项目,以便于自动填充。" }, "showIdentitiesInVaultView": { - "message": "在密码库视图中将支身份显示为自动填充建议" + "message": "在密码库视图中将身份显示为自动填充建议" }, "showIdentitiesCurrentTab": { "message": "在标签页上显示身份" @@ -1279,7 +1279,7 @@ "message": "页面加载时自动填充" }, "enableAutoFillOnPageLoadDesc": { - "message": "如果检测到登录表单,则在网页加载时执行自动填充。" + "message": "网页加载时如果检测到登录表单,则执行自动填充。" }, "autofillOnPageLoadWarning": { "message": "$OPENTAG$警告:$CLOSETAG$不完整或不信任的网站可以利用页面加载时的自动填充功能。", @@ -2090,7 +2090,7 @@ "message": "密码保护" }, "copyLink": { - "message": "Copy link" + "message": "复制链接" }, "copySendLink": { "message": "复制 Send 链接", @@ -3049,7 +3049,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "解锁您的账户以查看自动填充建议", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { @@ -3057,7 +3057,7 @@ "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "解锁您的账户(在新窗口中打开)", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { @@ -3081,27 +3081,27 @@ "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "新增登录", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "添加新的密码库登录项目(在新窗口中打开)", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "新增支付卡", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "添加新的密码库支付卡项目(在新窗口中打开)", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "新增身份", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "添加新的密码库身份项目(在新窗口中打开)", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { @@ -3221,7 +3221,7 @@ "message": "无效的文件密码,请使用您创建导出文件时输入的密码。" }, "destination": { - "message": "Destination" + "message": "目的地" }, "learnAboutImportOptions": { "message": "了解您的导入选项" @@ -3778,7 +3778,7 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "卡号结尾为", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { @@ -3806,7 +3806,7 @@ "message": "加载中" }, "data": { - "message": "Data" + "message": "数据" }, "assign": { "message": "分配" diff --git a/apps/browser/store/locales/hr/copy.resx b/apps/browser/store/locales/hr/copy.resx index dff95b37969..c71315011e6 100644 --- a/apps/browser/store/locales/hr/copy.resx +++ b/apps/browser/store/locales/hr/copy.resx @@ -118,58 +118,58 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden Password Manager + Bitwarden upravitelj lozinki - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Kod kuće, na poslu ili u pokretu, Bitwarden štiti sve tvoje lozinke, pristupne ključeve i osjetljive informacije. - Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! + PCMag, WIRED, The Verge, CNET, G2 i drugi su prepoznali Bitwarden kao najbolji upravitelj lozinki! -SECURE YOUR DIGITAL LIFE -Secure your digital life and protect against data breaches by generating and saving unique, strong passwords for every account. Maintain everything in an end-to-end encrypted password vault that only you can access. +OSIGURAJ SVOJ DIGITALNI ŽIVOT +Osiguraj svoj digitalni život i zaštiti se od povrede podataka generiranjem i spremanjem jedinstvenih, jakih lozinki za svaki račun. Održavaj sve u end-to-end šifriranom trezoru lozinki kojem samo ti možete pristupiti. -ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE -Easily manage, store, secure, and share unlimited passwords across unlimited devices without restrictions. +PRISTUPI SVOJIM PODACIMA, BILO GDJE, BILO KAD, NA BILO KOJEM UREĐAJU +Jednostavno upravljaj, pohrani, zaštiti i dijeli neograničen broj lozinki na neograničenom broju uređaja bez ograničenja. -EVERYONE SHOULD HAVE THE TOOLS TO STAY SAFE ONLINE -Utilize Bitwarden for free with no ads or selling data. Bitwarden believes everyone should have the ability to stay safe online. Premium plans offer access to advanced features. +SVATKO BI TREBAO IMATI ALATE ZA SIGURNOST NA MREŽI +Koristi Bitwarden besplatno, bez oglasa ili prodaje osobnoh podataka. Bitwarden vjeruje da bi svatko trebao imati mogućnost ostati siguran na internetu. Premium planovi nude pristup naprednim značajkama. -EMPOWER YOUR TEAMS WITH BITWARDEN -Plans for Teams and Enterprise come with professional business features. Some examples include SSO integration, self-hosting, directory integration and SCIM provisioning, global policies, API access, event logs, and more. +OSNAŽI SVOJE TIMOVE UZ BITWARDEN +Planovi za Teams i Enterprise dolaze s profesionalnim poslovnim značajkama. Neki primjeri uključuju SSO integraciju, vlastiti poslužitelj, integraciju imenika i SCIM pružanje usluga, globalna pravila, API pristup, zapisnike događaja i još mnogo toga. -Use Bitwarden to secure your workforce and share sensitive information with colleagues. +Koristi Bitwarden da osiguraš svoje zaposlenike i podijeliš osjetljive podatke s kolegama. -More reasons to choose Bitwarden: +Više razloga za odabir Bitwardena: -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +Enkripcija svjetske razine +Lozinke su zaštićene naprednom end-to-end enkripcijom (AES-256 bit, salted hashtag i PBKDF2 SHA-256) tako da tvoji podaci ostaju sigurni i privatni. -3rd-party Audits -Bitwarden regularly conducts comprehensive third-party security audits with notable security firms. These annual audits include source code assessments and penetration testing across Bitwarden IPs, servers, and web applications. +Revizije treće strane +Bitwarden je redovito podložan opsežnim sigurnosnim revizijama treće strane s poznatim sigurnosnim tvrtkama. Ove godišnje revizije uključuju procjene izvornog koda i testiranje penetracije preko Bitwarden IP adresa, poslužitelja i web aplikacija. -Advanced 2FA -Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. +Napredni 2FA +Osiguraj svoju prijavu autentifikatorom treće strane, kodovima poslanim e-poštom ili FIDO2 WebAuthn vjerodajnicama kao što je hardverski sigurnosni ključ ili pristupni ključ. Bitwarden Send -Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. +Prenesi podatke izravno drugima uz održavanje end-to-end kriptirane sigurnosti i ograničavanje izloženosti. -Built-in Generator -Create long, complex, and distinct passwords and unique usernames for every site you visit. Integrate with email alias providers for additional privacy. +Ugrađeni generator +Stvori dugačke, složene i jasne lozinke i jedinstvena korisnička imena za svaku stranicu koju posjetiš. Integriraj s pružateljima aliasa e-pošte za dodatnu privatnost. -Global Translations -Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. +Globalni prijevodi +Bitwarden je uz pomoć globalne zajednice putem Crowdina prevedan na više od 60 jezika, uključujući hrvatski. -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Višeplatformske aplikacije +Zaštiti i dijeli osjetljive podatke unutar svog Bitwarden trezora s bilo kojeg preglednika, mobilnog uređaja ili OS-a stolnog računala i više. -Bitwarden secures more than just passwords -End-to-end encrypted credential management solutions from Bitwarden empower organizations to secure everything, including developer secrets and passkey experiences. Visit Bitwarden.com to learn more about Bitwarden Secrets Manager and Bitwarden Passwordless.dev! +Bitwarden osigurava više od samih lozinki +End-to-end kriptirana rješenja za upravljanje vjerodajnicama iz Bitwardena osnažuju organizacije da osiguraju sve, uključujući razvojne tajne i iskustva s pristupnim ključem. Posjetite Bitwarden.com kako biste saznali više o Bitwarden Secrets Manageru i Bitwarden Passwordless.dev! - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Kod kuće, na poslu ili u pokretu, Bitwarden štiti sve tvoje lozinke, pristupne ključeve i osjetljive informacije. Sinkroniziraj i pristupi svojem trezoru s više uređaja From beb5a65cda29d2a85f942b9ad50cb23eb2c80124 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 12:33:00 +0000 Subject: [PATCH 17/46] Autosync the updated translations (#10314) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/az/messages.json | 86 ++--- apps/web/src/locales/bg/messages.json | 46 +-- apps/web/src/locales/de/messages.json | 60 +-- apps/web/src/locales/fi/messages.json | 2 +- apps/web/src/locales/hr/messages.json | 458 +++++++++++------------ apps/web/src/locales/hu/messages.json | 2 +- apps/web/src/locales/ja/messages.json | 38 +- apps/web/src/locales/lv/messages.json | 50 +-- apps/web/src/locales/sk/messages.json | 56 +-- apps/web/src/locales/uk/messages.json | 70 ++-- apps/web/src/locales/zh_CN/messages.json | 56 +-- 11 files changed, 462 insertions(+), 462 deletions(-) diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 49dd882cad0..5adfe3f97d3 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -571,7 +571,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Elementlər bura daşındı: $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -580,7 +580,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Element bura daşındı: $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -646,16 +646,16 @@ "message": "Seansın müddəti bitdi." }, "restartRegistration": { - "message": "Restart registration" + "message": "Qeydiyyatı yenidən başlat" }, "expiredLink": { - "message": "Expired link" + "message": "Vaxtı bitmiş keçid" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Lütfən qeydiyyatı yenidən başladın və ya giriş etməyə çalışın." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Artıq bir hesabınız ola bilər" }, "logOutConfirmation": { "message": "Çıxış etmək istədiyinizə əminsiniz?" @@ -1507,7 +1507,7 @@ "message": "Xaricə köçürülən faylın şifrəsi açılarkən xəta baş verdi. Şifrələmə açarınız, datanı xaricə köçürmək üçün istifadə edilən şifrələmə açarı ilə uyuşmur." }, "destination": { - "message": "Destination" + "message": "Hədəf" }, "learnAboutImportOptions": { "message": "Daxilə köçürmə seçimlərinizi öyrənin" @@ -3460,7 +3460,7 @@ "message": "Yuxarıdakı təşkilata qoşulmaq üçün dəvət edildiniz. Dəvəti qəbul etmək üçün Bitwarden hesabına giriş etməli və ya yeni bir hesab yaratmalısınız." }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Bu ana parol təyin edərək bu təşkilata qoşulmağı tamamlayın." }, "inviteAccepted": { "message": "Dəvət qəbul edildi" @@ -3820,7 +3820,7 @@ "message": "Heç nə seçmədiniz." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Bitwarden-in tövsiyə, elan və araşdırma imkanlarını gələn qutunuzda əldə edin." }, "unsubscribe": { "message": "Abunəlikdən çıx" @@ -4274,7 +4274,7 @@ "message": "Bu təşkilat üçün SSO əlaqəsini kəsmək istədiyinizə əminsiniz?" }, "linkSso": { - "message": "SSO bağlantısını yarat" + "message": "SSO ilə əlaqələndir" }, "singleOrg": { "message": "Tək təşkilat" @@ -4383,14 +4383,14 @@ "message": "Ləğv edildi" }, "sendLink": { - "message": "\"Send\" bağlantısı", + "message": "\"Send\" keçidi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Keçidi kopyala" }, "copySendLink": { - "message": "\"Send\" bağlantısını kopyala", + "message": "\"Send\" keçidini kopyala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "removePassword": { @@ -4767,10 +4767,10 @@ "message": "Göndərmək istədiyiniz fayl." }, "copySendLinkOnSave": { - "message": "Saxladıqdan sonra bu \"Send\"in paylaşma bağlantısını lövhəmə kopyala." + "message": "Saxladıqdan sonra bu \"Send\"in paylaşma keçidini lövhəmə kopyala." }, "sendLinkLabel": { - "message": "\"Send\" bağlantısı", + "message": "\"Send\" keçidi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "send": { @@ -4808,61 +4808,61 @@ "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." }, "centralizeSecretsManagement": { - "message": "Centralize secrets management." + "message": "Sirlərin idarə edilməsini mərkəzləşdirin." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Sirlərin təşkilatınızda yayılmasını önləmək üçün sirləri güvənli şəkildə saxlayın və idarə edin." }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "Sirr sızıntılarını önləyin." }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "Sirləri ucdan-uca şifrələmə ilə qoruyun. Artıq sabit kodlaşdırma sirlərinə və ya .env faylları üzərindən paylaşmağa ehtiyac yoxdur." }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "Tərtibatçı məhsuldarlığını artır." }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "Tərtibatçıların, kod keyfiyyətini yaxşılaşdırmaq kimi vacib mövzulara fokuslana bilməsi üçün \"runtime\"da sirləri proqramlı şəkildə alın və yerləşdirin." }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "Biznes təhlükəsizliyini gücləndirin." }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "SSO inteqrasiyaları, \"event\" jurnalları və \"access rotation\" ilə maşın və insanların sirlərə müraciətinə ciddi nəzarət edin." }, "tryItNow": { - "message": "Try it now" + "message": "İndi sına" }, "sendRequest": { - "message": "Send request" + "message": "Tələb göndər" }, "addANote": { - "message": "Add a note" + "message": "Not əlavə et" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Bitwarden Sirr Meneceri" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Bitwarden-dən daha çox məhsul" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "\"Sirr Meneceri\"nə müraciət tələb et" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "\"Sirr Meneceri\"ni sınamaq üçün administratorunuzun təsdiqi lazımdır." }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "Sirr menecerinə müraciət tələbi üçün e-poçt adminlərə göndərildi." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Salam,\n\nBu, komandamız üçün \"Bitwarden Sirr Meneceri\"nə abunə olmaq istəyidir. Dəstəyiniz, bizim üçün böyük məna kəsb edir!\n\nBitwarden Sirr Meneceri, API açarları, databaza parolları və autentifikasiya sertifikatları kimi maşın kimlik məlumatlarını güvənli şəkildə saxlamaq, paylaşmaq və yerləşdirmək üçün ucdan-uca şifrələnmiş sirlərin idarə edilməsi həllidir.\n\nSirr Meneceri, bizə belə kömək edəcək:\n\n- Güvənliyi artırmaq\n- Əməliyyatları asanlaşdırmaq\n- Dəyərli sirr sızıntılarını önləmək\n\nKomandamız üçün ödənişsiz sınağı tələb etmək üçün lütfən Bitwarden ilə əlaqə saxlayın.\n\nKöməyiniz üçün təşəkkürlər!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "Üzvlərə müraciət icazəsi vermə:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "Sirr Menecerinə müraciət icazəsi vermək üçün üzvləri görün və seçin." }, "openYourOrganizations": { "message": "Open your organization's" @@ -4899,7 +4899,7 @@ } }, "viewSendHiddenEmailWarning": { - "message": "Bu \"Send\"i yaradan Bitwarden istifadəçisi e-poçt ünvanını gizlətməyi seçdi. İstifadə etməzdən və ya endirməzdən əvvəl bu bağlantının mənbəyinin etibarlı olduğuna əmin olmalısınız.", + "message": "Bu \"Send\"i yaradan Bitwarden istifadəçisi e-poçt ünvanını gizlətməyi seçib. İstifadə etməzdən və ya endirməzdən əvvəl bu keçidin mənbəyinin etibarlı olduğuna əmin olmalısınız.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDateIsInvalid": { @@ -4975,7 +4975,7 @@ } }, "eventResetSsoLink": { - "message": "$ID$ istifadəçisi üçün SSO bağlantısını sıfırla", + "message": "$ID$ istifadəçisi üçün SSO keçidini sıfırla", "placeholders": { "id": { "content": "$1", @@ -5508,7 +5508,7 @@ "message": "Ailə sirləri üçün paylaşılan kolleksiyalar" }, "badToken": { - "message": "Bağlantı artıq etibarlı deyil. Lütfən sponsorun təklifi yenidən göndərməsini təmin edin." + "message": "Keçid, artıq etibarlı deyil. Lütfən sponsorun təklifi yenidən göndərməsini təmin edin." }, "reclaimedFreePlan": { "message": "Geri alınmış ödənişsiz plan" @@ -7997,10 +7997,10 @@ "message": "Bu kolleksiyalara təyin et" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Yalnız bu kolleksiyalara müraciəti olan təşkilat üzvləri bu elementi görə biləcək." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Yalnız bu kolleksiyalara müraciəti olan təşkilat üzvləri bu elementləri görə biləcək." }, "selectCollectionsToAssign": { "message": "Təyin ediləcək kolleksiyaları seçin" @@ -8655,10 +8655,10 @@ "message": "Qovluq seç" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 element seçilmiş təşkilata birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ element seçilmiş təşkilata birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", "placeholders": { "personal_items_count": { "content": "$1", @@ -8667,7 +8667,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 element $ORG$ təşkilatına birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", "placeholders": { "org": { "content": "$1", @@ -8676,7 +8676,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ element $ORG$ təşkilatına birdəfəlik transfer ediləcək. Artıq bu elementlərə sahib olmaya bilməyəcəksiniz.", "placeholders": { "personal_items_count": { "content": "$1", diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 2e91d7fe638..86cba4a4a3e 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Копиране на връзката" }, "copySendLink": { "message": "Копиране на връзката към изпратеното", @@ -4805,73 +4805,73 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + "message": "Екипите по разработка, софтуерни операции и инфраструктура избират Управлението на тайни на Битуорден, за да управляват и внедряват по сигурен начин своите тайни данни свързани с инфраструктурата и конкретни машини." }, "centralizeSecretsManagement": { - "message": "Centralize secrets management." + "message": "Централизирайте управлението на тайни." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Съхранявайте и управлявайте сигурно тайните си данни на едно място, за да предотвратите разгласяването им из организацията." }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "Предотвратете изтичането на тайни данни." }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "Защитете тайните си данни с шифроване от край до край. Без повече тайни в кода или споделяне чрез файлове „.env“." }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "Подобрете производителността на разработчиците." }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "Изтегляйте и внедрявайте тайни в процеса на изпълнение на приложенията, така че разработчиците да могат да се концентрират върху това, в което са най-добри – да подобряват качеството на кода." }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "Подсилете сигурността на бизнеса си." }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "Упражнявайте стриктен контрол върху достъпа на машини и хора до тайните данни с внедряване на еднократно удостоверяване, журнали на събитията и завъртане на достъпа." }, "tryItNow": { - "message": "Try it now" + "message": "Изпробвайте сега" }, "sendRequest": { - "message": "Send request" + "message": "Изпращане на зайвка" }, "addANote": { - "message": "Add a note" + "message": "Добавете бележка" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Управление на тайни от Битуорден" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Още продукти от Битуорден" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "Заявете достъп до Управлението на тайни" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "Необходимо е одобрение от администратор, за да изпробвате Управлението на тайни." }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "Заявката за достъп до Управлението на данни е изпратена по е-поща до администраторите." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Здравейте!\n\nИмам нужда от абонамент за Управлението на тайни на Битуорден за нашия екип. Подкрепата Ви ще означава много за нас!\n\nУправлението на тайни на Битуорден е решение за управлението на тайни данни с шифроване от край до край, чрез което могат да се съхраняват, споделят и внедряват данни за удостоверяване на различни машини, като ключове за ППИ, пароли за бази данни и сертификати.\n\nУправлението на тайни ще ни помогне да:\n – подобрим сигурността си;\n – уеднаквим операционните си процеси;\n – предотвратим потенциални изтичания на тайни данни.\n\nМоля, свържете се с Битуорден, за да направите заявка за безплатен пробен период.\n\nБлагодаря предварително за помощта!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "Даване на достъп за членовете:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "прегледайте и изберете членовете, на които искате да дадете достъп до Управлението на тайни." }, "openYourOrganizations": { "message": "Open your organization's" }, "usingTheMenuSelect": { - "message": "Using the menu, select" + "message": "Използвайки менюто, изберете" }, "toGrantAccessToSelectedMembers": { - "message": "to grant access to selected members." + "message": ", за да дадете достъп на избраните членове." }, "sendVaultCardTryItNow": { "message": "пробвайте още сега", diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index b4e812d819c..774eccfbfee 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -571,7 +571,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Einträge verschoben nach $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -580,7 +580,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Eintrag verschoben nach $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -1507,7 +1507,7 @@ "message": "Fehler beim Entschlüsseln der exportierten Datei. Dein Verschlüsselungsschlüssel stimmt nicht mit dem beim Export verwendeten Verschlüsselungsschlüssel überein." }, "destination": { - "message": "Destination" + "message": "Ziel" }, "learnAboutImportOptions": { "message": "Erfahre mehr über deine Importoptionen" @@ -3460,7 +3460,7 @@ "message": "Du wurdest eingeladen, dem oben genannten Organisation beizutreten. Um die Einladung anzunehmen, musst du ein Bitwarden-Konto erstellen oder dich mit deinem bestehenden Bitwarden-Konto anmelden." }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Schließe den Beitritt zu dieser Organisation ab, indem du ein Master-Passwort festlegst." }, "inviteAccepted": { "message": "Einladung angenommen" @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Link kopieren" }, "copySendLink": { "message": "Send-Link kopieren", @@ -4805,61 +4805,61 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + "message": "Entwickler, DevOps und IT-Teams wählen den Bitwarden Secrets Manager aus, um ihre Infrastruktur- und Maschinengeheimnisse sicher zu verwalten und bereitzustellen." }, "centralizeSecretsManagement": { - "message": "Centralize secrets management." + "message": "Geheimnisverwaltung zentralisieren." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Speicher und verwalte Geheimnisse sicher an einem Ort, um die unkontrollierte Ausbreitung von Geheimnissen in deinem Unternehmen zu verhindern." }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "Verhinderung von Geheimdatenlecks." }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "Schütze Geheimnisse mit Ende-zu-Ende-Verschlüsselung. Keine fest kodierten Geheimnisse mehr oder Teilen über .env-Dateien." }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "Steigerung der Produktivität der Entwickler." }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "Programmgesteuertes Abrufen und Bereitstellen von Geheimnissen zur Laufzeit, damit sich die Entwickler auf das Wesentliche konzentrieren können, nämlich die Verbesserung der Codequalität." }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "Stärkung der Unternehmenssicherheit." }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "Behalte mit SSO-Integrationen, Ereignisprotokollen und Zugriffsrotation eine strenge Kontrolle über den maschinellen und menschlichen Zugriff auf Geheimnisse." }, "tryItNow": { - "message": "Try it now" + "message": "Jetzt ausprobieren" }, "sendRequest": { - "message": "Send request" + "message": "Anfrage absenden" }, "addANote": { - "message": "Add a note" + "message": "Eine Notiz hinzufügen" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Mehr Produkte von Bitwarden" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "Zugriff auf Secrets Manager anfragen" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "Du benötigst die Genehmigung deines Administrators, um den Secrets Manager auszuprobieren." }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "E-Mail mit Zugriffsanfrage für Secrets Manager an Administratoren gesendet." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Hi,\n\nich möchte ein Abonnement des Bitwarden Secrets Manager für unser Team beantragen. Deine Unterstützung würde eine Menge bedeuten!\n\nDer Bitwarden Secrets Manager ist eine Ende-zu-Ende-verschlüsselte Verwaltungslösung für das sichere Aufbewahren, Teilen und Bereitstellen von Maschinen-Zugangsdaten wie API-Schlüssel, Datenbank-Passwörter und Authentifizierungszertifikate.\n\nSecrets Manager hilft uns bei der:\n\n- Verbesserung der Sicherheit\n- Rationalisierung von Abläufen\n- Vermeidung kostspieliger Geheimdatenlecks\n\nUm eine kostenlose Testversion für unser Team anzufordern, wende dich bitte an Bitwarden.\n\nVielen Dank für deine Hilfe!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "Mitgliedern Zugriff geben:" }, "viewAndSelectTheMembers": { "message": "view and select the members you want to give access to Secrets Manager." @@ -7997,10 +7997,10 @@ "message": "Diesen Sammlungen zuweisen" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Nur Organisationsmitglieder mit Zugriff auf diese Sammlungen können die Einträge sehen." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Nur Organisationsmitglieder mit Zugriff auf diese Sammlungen können die Einträge sehen." }, "selectCollectionsToAssign": { "message": "Zu zuweisende Sammlungen auswählen" @@ -8655,10 +8655,10 @@ "message": "Ordner auswählen" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 Eintrag wird dauerhaft an die ausgewählte Organisation übertragen. Du wirst diesen Eintrag nicht mehr besitzen." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an die ausgewählte Organisation übertragen. Du wirst diese Einträge nicht mehr besitzen.", "placeholders": { "personal_items_count": { "content": "$1", @@ -8667,7 +8667,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 Eintrag wird dauerhaft an $ORG$ übertragen. Du wirst diesen Eintrag nicht mehr besitzen.", "placeholders": { "org": { "content": "$1", @@ -8676,7 +8676,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ werden dauerhaft an $ORG$ übertragen. Du wirst diese Einträge nicht mehr besitzen.", "placeholders": { "personal_items_count": { "content": "$1", @@ -8689,7 +8689,7 @@ } }, "data": { - "message": "Data" + "message": "Daten" }, "purchasedSeatsRemoved": { "message": "erworbene Benutzerplätze entfernt" diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index d51a55e27a7..004d8d77c88 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Kopioi linkki" }, "copySendLink": { "message": "Kopioi Send-linkki", diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index e09ad842e94..f4d46fee8fe 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -43,10 +43,10 @@ "message": "Vlasnik platne kartice" }, "loginCredentials": { - "message": "Login credentials" + "message": "Vjerodajnice za prijavu" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Kôd za provjeru" }, "number": { "message": "Broj" @@ -145,13 +145,13 @@ "message": "Ključ autentifikatora (TOTP)" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Učini dvostruku autentifikaciju besprijekornom" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden može pohraniti i ispuniti kodove za dvostruku autentifikaciju. Kopiraj i zalijepi ključ u ovo polje." }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden može pohraniti i ispuniti kodove za dvostruku autentifikaciju. Odaberi ikonu kamere i označi QR kôd za provjeru autentičnosti ove web stranice ili kopiraj i zalijepi ključ u ovo polje." }, "folder": { "message": "Mapa" @@ -189,7 +189,7 @@ "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { - "message": "You", + "message": "Ti", "description": "Used as a label to indicate that the user is the owner of an item." }, "addFolder": { @@ -421,13 +421,13 @@ "message": "Stavka" }, "itemDetails": { - "message": "Item details" + "message": "Detalji stavke" }, "itemName": { - "message": "Item name" + "message": "Naziv stavke" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "S dopuštenjima samo za prikaz ne možeš ukloniti zbirke: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -571,7 +571,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Stavke premještene u $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -580,7 +580,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Stavka premještena u $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -631,31 +631,31 @@ "message": "Pristup" }, "accessLevel": { - "message": "Access level" + "message": "Razina pristupa" }, "accessing": { - "message": "Accessing" + "message": "Pristupanje" }, "loggedOut": { "message": "Odjavljen/a" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Odjavljen/a si sa svog računa." }, "loginExpired": { "message": "Sesija je istekla." }, "restartRegistration": { - "message": "Restart registration" + "message": "Ponovno pokreni registraciju" }, "expiredLink": { - "message": "Expired link" + "message": "Istekla poveznica" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Ponovno pokreni registraciju ili se pokušaj prijaviti." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Možda već imaš račun" }, "logOutConfirmation": { "message": "Sigurno se želiš odjaviti?" @@ -718,7 +718,7 @@ "message": "Ostavi ovaj prozor otvoren i prati upute u svojem pregledniku." }, "errorCreatingPasskey": { - "message": "Greška kreiranja pristupnog ključa" + "message": "Greška stvaranja pristupnog ključa" }, "errorCreatingPasskeyInfo": { "message": "Došlo je do problema sa stvaranjem pristupnog ključa." @@ -778,10 +778,10 @@ "message": "Stvori račun" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Postavi jaku lozinku" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Dovrši stvaranje svog računa postavljanjem lozinke" }, "newAroundHere": { "message": "Novi korisnik?" @@ -793,7 +793,7 @@ "message": "Prijavi se" }, "verifyIdentity": { - "message": "Verify your Identity" + "message": "Potvrdi svoj identitet" }, "logInInitiated": { "message": "Pokrenuta prijava" @@ -832,7 +832,7 @@ "message": "Podsjetnik glavne lozinke" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Podsjetnik ti možemo poslati ako zaboraviš svoju lozinku. Najviše $CURRENT$/$MAXIMUM$ znakova.", "placeholders": { "current": { "content": "$1", @@ -882,7 +882,7 @@ "message": "Potvrda glavne lozinke se ne podudara." }, "newAccountCreated": { - "message": "Tvoj novi račun je kreiran! Sada se možeš prijaviti." + "message": "Tvoj novi račun je stvoren! Sada se možeš prijaviti." }, "trialAccountCreated": { "message": "Račun je uspješno stvoren." @@ -900,7 +900,7 @@ "message": "Adresa e-pošte" }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Trezor je zaključan" }, "uuid": { "message": "UUID" @@ -1027,17 +1027,17 @@ "message": "Autentifikatorska aplikacija" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Unesi kôd generiran autentifikatorskom aplikacijom kao npr. Bitwarden Authenticatorom.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP security key" + "message": "Yubico OTP sigurnosni ključ" }, "yubiKeyDesc": { - "message": "Koristi YubiKey za pristup svojem računu. Radi s YubiKey 4, 4 Nano, 4C i NEO uređajima." + "message": "Koristi YubiKey 4, 5 ili NEO uređaj." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Unesi kôd generiran Duo Securityjem.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1051,10 +1051,10 @@ "message": "FIDO U2F sigurnosni ključ" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Pristupni ključ" }, "webAuthnDesc": { - "message": "Koristi WebAuthn sigurnosni ključ za pristup svojem računu." + "message": "Koristi biometriju uređaja ili FIDO2 kompatibilan sigurnosni ključ." }, "webAuthnMigrated": { "message": "(migrirano s FIDO)" @@ -1063,7 +1063,7 @@ "message": "E-pošta" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "Unesi kôd poslan e-poštom." }, "continue": { "message": "Nastavi" @@ -1105,7 +1105,7 @@ "message": "Sigurno želiš nastaviti?" }, "moveSelectedItemsDesc": { - "message": "Choose a folder that you would like to add the $COUNT$ selected item(s) to.", + "message": "Odaberi mapu u koju želiš premjestiti odabranih $COUNT$ stavke/i.", "placeholders": { "count": { "content": "$1", @@ -1140,10 +1140,10 @@ "message": "Kopiraj UUID" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Pogreška osvježavanja tokena pristupa" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Nije pronađen token za osvježavanje ili API ključevi. Pokušaj se odjaviti i ponovno prijaviti." }, "warning": { "message": "Upozorenje" @@ -1152,7 +1152,7 @@ "message": "Potvrdi izvoz trezora" }, "confirmSecretsExport": { - "message": "Potvrdi export trezora" + "message": "Potvrdi izvoz tajni" }, "exportWarningDesc": { "message": "Ovaj izvoz sadrži podatke trezora u nešifriranom obliku! Izvezenu datoteku se ne bi smjelo pohranjivati ili slati putem nesigurnih kanala (npr. e-poštom). Izbriši ju odmah nakon završetka korištenja." @@ -1440,7 +1440,7 @@ "message": "Tvoj račun je zatvoren i svi povezani podaci su obrisani." }, "deleteOrganizationWarning": { - "message": "Deleting your organization is permanent. It cannot be undone." + "message": "Brisanje tvoje organizacije je trajno i naknadno ju nije moguće vratiti." }, "myAccount": { "message": "Moj račun" @@ -1452,19 +1452,19 @@ "message": "Uvezi podatke" }, "onboardingImportDataDetailsPartOne": { - "message": "If you don't have any data to import, you can create a ", + "message": "Ako nemaš podataka za uvoz možeš stvoriti ", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsLink": { - "message": "new item", + "message": "novu stavku", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsPartTwoNoOrgs": { - "message": " instead.", + "message": ".", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead." }, "onboardingImportDataDetailsPartTwoWithOrgs": { - "message": " instead. You may need to wait until your administrator confirms your organization membership.", + "message": ". Možda ćeš morati pričekati da tvoj administrator potvrdi tvoje članstvo u organizaciji.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "importError": { @@ -1507,7 +1507,7 @@ "message": "Greška u dešifriranju izvozne datoteke. Ovaj ključ za šifriranje ne odgovara ključu za šifriranje korištenom pri izvozu datoteke." }, "destination": { - "message": "Destination" + "message": "Odredište" }, "learnAboutImportOptions": { "message": "Više o mogućnostima uvoza" @@ -1704,19 +1704,19 @@ "message": "Unesi glavnu lozinku za promjenu postavki prijave u dva koraka." }, "twoStepAuthenticatorInstructionPrefix": { - "message": "Download an authenticator app such as" + "message": "Preuzmi autentifikatorsku aplikaciju kao" }, "twoStepAuthenticatorInstructionInfix1": { "message": "," }, "twoStepAuthenticatorInstructionInfix2": { - "message": "or" + "message": "ili" }, "twoStepAuthenticatorInstructionSuffix": { "message": "." }, "continueToExternalUrlTitle": { - "message": "Continue to $URL$?", + "message": "Nastavi na $URL$?", "placeholders": { "url": { "content": "$1", @@ -1725,25 +1725,25 @@ } }, "continueToExternalUrlDesc": { - "message": "You are leaving Bitwarden and launching an external website in a new window." + "message": "Napuštaš Bitwarden i otvaraš vanjsku web stranicu u novom prozoru." }, "twoStepContinueToBitwardenUrlTitle": { - "message": "Continue to bitwarden.com?" + "message": "Nastavi na bitwarden.com?" }, "twoStepContinueToBitwardenUrlDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website." + "message": "Bitwarden autentifikator omogućuje pohranu ključeva za autentifikaciju i generiranje TOTP kodova za dvostruku autentifikaciju. Saznaj više na bitwarden.com." }, "twoStepAuthenticatorScanCodeV2": { - "message": "Scan the QR code below with your authenticator app or enter the key." + "message": "Skeniraj donji QR kôd svojom autentifikatorskom aplikacijom ili unesi ključ." }, "twoStepAuthenticatorQRCanvasError": { - "message": "Could not load QR code. Try again or use the key below." + "message": "Nije moguće učitati QR kôd. Pokušaj ponovno ili koristi donji ključ." }, "key": { "message": "Ključ" }, "twoStepAuthenticatorEnterCodeV2": { - "message": "Verification code" + "message": "Kôd za provjeru" }, "twoStepAuthenticatorReaddDesc": { "message": "Ako trebaš dodati novi uređaj, dolje se nalazi QR kôd (ili ključ) kojeg zahtijeva tvoja autentifikatorska aplikacija." @@ -1824,10 +1824,10 @@ "message": "Unesi podatke o Bitwarden aplikaciji iz svoje Duo Admin ploče." }, "twoFactorDuoClientId": { - "message": "Client Id" + "message": "ID klijenta" }, "twoFactorDuoClientSecret": { - "message": "Client Secret" + "message": "Klijentova tajna" }, "twoFactorDuoApiHostname": { "message": "API Hostname" @@ -1923,7 +1923,7 @@ "message": "Pronađena neosigurana web mjesta" }, "unsecuredWebsitesFoundReportDesc": { - "message": "We found $COUNT$ items in your $VAULT$ with unsecured URIs. You should change their URI scheme to https:// if the website allows it.", + "message": "Pronašli smo $COUNT$ stavki u tvom trezoru koje koriste neosigurane URI-je (http://). Ako web mjesto podržava, trebalo bi URI-je promijeniti u https://", "placeholders": { "count": { "content": "$1", @@ -1948,7 +1948,7 @@ "message": "Prijave na kojima nije omogućena dvostruka autentifikacija" }, "inactive2faFoundReportDesc": { - "message": "We found $COUNT$ website(s) in your $VAULT$ that may not be configured with two-step login (according to 2fa.directory). To further protect these accounts, you should set up two-step login.", + "message": "Pronašli smo $COUNT$ web mjesto/a u tvom $VAULT$ za koje nije omogućena prijava dvostrukom autentifikacijom (izvor: 2fa.directory). Za bolju zaštitu ovih računa, omogući dvostruku autentifikaciju na savkom računu zasebno.", "placeholders": { "count": { "content": "$1", @@ -1976,7 +1976,7 @@ "message": "Pronađene izložene lozinke" }, "exposedPasswordsFoundReportDesc": { - "message": "We found $COUNT$ items in your $VAULT$ that have passwords that were exposed in known data breaches. You should change them to use a new password.", + "message": "Pronašli smo $COUNT$ stavki u tvom $VAULT$ koje imaju lozinke koje su otkrivene prilikom znanih curenja podataka. Trebalo bi ih zamijentii novim lozinkama.", "placeholders": { "count": { "content": "$1", @@ -2013,7 +2013,7 @@ "message": "Pronađene slabe lozinke" }, "weakPasswordsFoundReportDesc": { - "message": "We found $COUNT$ items in your $VAULT$ with passwords that are not strong. You should update them to use stronger passwords.", + "message": "Pronašli smo $COUNT$ stavki u tvom $VAULT$ s lozinkama koje nisu jake. Trebalo bi ih zamijeniti jakim lozinkama.", "placeholders": { "count": { "content": "$1", @@ -2038,7 +2038,7 @@ "message": "Pronađene iste lozinke" }, "reusedPasswordsFoundReportDesc": { - "message": "We found $COUNT$ passwords that are being reused in your $VAULT$. You should change them to a unique value.", + "message": "Pronašli smo $COUNT$ istih lozinki u tvom $VAULT$. Trebalo bi ih zamijeniti jedinstvenim lozinkama.", "placeholders": { "count": { "content": "$1", @@ -2456,7 +2456,7 @@ "message": "Kontaktiraj službu za korisnike" }, "contactSupportShort": { - "message": "Kontaktirajte podršku" + "message": "Kontaktiraj podršku" }, "updatedPaymentMethod": { "message": "Ažurirani način plaćanja." @@ -2674,7 +2674,7 @@ } }, "trialSecretsManagerThankYou": { - "message": "Thanks for signing up for Bitwarden Secrets Manager for $PLAN$!", + "message": "Hvala na prijavi za $PLAN$ Bitwarden Secrets Manager!", "placeholders": { "plan": { "content": "$1", @@ -2881,10 +2881,10 @@ "message": "Sve" }, "addAccess": { - "message": "Add Access" + "message": "Dodaj pristup" }, "addAccessFilter": { - "message": "Add Access Filter" + "message": "Dodaj pristupni filter" }, "refresh": { "message": "Osvježi" @@ -2923,7 +2923,7 @@ "message": "Bitwarden Web trezor" }, "bitSecretsManager": { - "message": "Bitwarden Upravitelj tajni" + "message": "Bitwarden Secrets Manager" }, "loggedIn": { "message": "Prijava" @@ -2953,7 +2953,7 @@ "message": "Neispravan kôd" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "Neispravan PIN" }, "exportedVault": { "message": "Trezor izvezen" @@ -3334,25 +3334,25 @@ "message": "Uređaj" }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Stvaranje računa na" }, "checkYourEmail": { - "message": "Check your email" + "message": "Provjeri svoju e-poštu" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Slijedi vezu u e-pošti poslanoj na" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "za nastavak stvaranja tvojeg računa." }, "noEmail": { - "message": "No email?" + "message": "Nema e-pošte?" }, "goBack": { - "message": "Go back" + "message": "Nazad" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "na uređivanje svoje adrese e-pošte." }, "view": { "message": "Prikaz" @@ -3436,7 +3436,7 @@ "message": "Adresa e-pošte je provjerena" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "e-pošta potvrđena" }, "emailVerifiedFailed": { "message": "Ne možeš potvrditi svoju e-poštu? Pošalji novu poruku." @@ -3460,7 +3460,7 @@ "message": "Primljen je poziv za pridruživanje gore navedenoj organizaciji. Za prihvaćanje poziva potrebno je prijaviti se na svoj postojeći Bitwarden račun ili stvoriti novi." }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Dovrši pridruživanje organizaciji postavljanjem glavne lozinke." }, "inviteAccepted": { "message": "Poziv prihvaćen" @@ -3508,7 +3508,7 @@ "message": "Zatraženo je brisanje tvojeg Bitwarden računa. Klikni u nastavku za potvrdu brisanja računa." }, "deleteRecoverOrgConfirmDesc": { - "message": "You have requested to delete your Bitwarden organization." + "message": "Zatraženo je brisanje tvoje Bitwarden organizacije." }, "myOrganization": { "message": "Moja organizacija" @@ -3637,7 +3637,7 @@ "message": "Ograniči broj korisnika u pretplati. Kada je broj dosegnut, neće biti moguće pozvati nove korisnike." }, "limitSmSubscriptionDesc": { - "message": "Ograniči broj korisnika u pretplati. Kada je broj dosegnut, neće biti moguće pozvati nove korisnike." + "message": "Ograniči broj korisnika u pretplati za Secrets Manager. Kada je broj dosegnut, neće biti moguće pozvati nove korisnike." }, "maxSeatLimit": { "message": "Najveći dozvoljeni broj korisnika (opcionalno)", @@ -3676,7 +3676,7 @@ "message": "Preplata ažurirana" }, "subscribedToSecretsManager": { - "message": "Pretplata ažurirana. Sada imaš pristup Upravitelju tajni." + "message": "Pretplata ažurirana. Sada imaš pristup Secrets Manageru." }, "additionalOptions": { "message": "Dodatne postavke" @@ -3688,10 +3688,10 @@ "message": "Promjene na pretplati rezultirati će proporcionalnim izmjenama ukupnog zaduženja. Ako novopozvanim korisnikom prekoračiš broj licenci, odmah će biti naplaćeno proporcionalno uvećanje za nove korisnike." }, "smStandaloneTrialSeatCountUpdateMessageFragment1": { - "message": "If you want to add additional" + "message": "Za dodavanje" }, "smStandaloneTrialSeatCountUpdateMessageFragment2": { - "message": "seats without the bundled offer, please contact" + "message": "dodatnih pretplatničkih mjesta bez ponude u paketu, obrati se" }, "subscriptionUserSeatsLimitedAutoscale": { "message": "Promjene na pretplati rezultirati će proporcionalnim izmjenama ukupnog zaduženja. Ako novopozvanim korisnikom prekoračiš broj licenci, odmah će biti naplaćeno proporcionalno uvećanje za nove korisnike dok se ne dosegne krajnji broj licenci ($MAX$).", @@ -3703,7 +3703,7 @@ } }, "subscriptionUserSeatsWithoutAdditionalSeatsOption": { - "message": "Možeš pozvati do $COUNT$ članova bez dodatnih troškova. Kontaktiraj korisničku podršku kako bi nadogradio plan i pozvao više članova.", + "message": "Možeš pozvati do $COUNT$ članova bez dodatnih troškova. Kontaktiraj korisničku podršku za nadogradnju plana i pozivanje više članova.", "placeholders": { "count": { "content": "$1", @@ -3748,7 +3748,7 @@ } }, "subscriptionSeatMaxReached": { - "message": "You cannot invite more than $COUNT$ members without increasing your subscription seats.", + "message": "Ne možeš pozvati više od $COUNT$ članova bez povećanja broja pretplatničkih mjesta.", "placeholders": { "count": { "content": "$1", @@ -3784,7 +3784,7 @@ "message": "Ažuriraj ključ za šifriranje" }, "updateEncryptionSchemeDesc": { - "message": "We've changed the encryption scheme to provide better security. Update your encryption key now by entering your master password below." + "message": "Promijenili smo shemu šifriranja kako bismo pružili bolju sigurnost. Ažuriraj odmah svoj ključ za šifriranje unošenjem svoje glavne lozinke." }, "updateEncryptionKeyWarning": { "message": "Nakon ažuriranja svojeg ključa za šifriranje, obavezno se trebaš odjaviti i ponovno prijaviti u sve Bitwarden aplikacije koje trenutno koristiš (npr. mobilna aplikacija, proširenje preglednika, ...). Ako se ne odjaviš i ponovno prijaviš (čime se preuzima tvoj novi ključ za šifriranje) može doći do oštećenja spremljenih podataka. Pokušati ćemo te automatski odjaviti, no, to bi možda moglo potrajati." @@ -3820,19 +3820,19 @@ "message": "Ništa nije odabrano." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Primaj e-poštom od Bitwardena savjete, najave i mogućnosti istraživanja." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Poništi pretplatu" }, "atAnyTime": { - "message": "at any time." + "message": "bilo kada." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Ako nastaviš, slažeš se s" }, "and": { - "message": "and" + "message": "i" }, "acceptPolicies": { "message": "Označavanjem ove kućice slažete se sa sljedećim:" @@ -3898,13 +3898,13 @@ "message": "Stavkama u suspendiranoj Organizaciji se ne može pristupiti. Kontaktiraj vlasnika Organizacije za pomoć." }, "secretsCannotCreate": { - "message": "Secrets cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "Nije moguće stvoriti Tajne u suspendiranim organizacijama. Kontaktiraj vlasnika tvoje organizacije za pomoć." }, "projectsCannotCreate": { - "message": "Projects cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "Nije moguće stvoriti Projekte u suspendiranim organizacijama. Kontaktiraj vlasnika tvoje organizacije za pomoć." }, "serviceAccountsCannotCreate": { - "message": "Service accounts cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "Nije moguće stvoriti Servisne račune u suspendiranim organizacijama. Kontaktiraj vlasnika tvoje organizacije za pomoć." }, "disabledOrganizationFilterError": { "message": "Stavkama u suspendiranoj Organizaciji se ne može pristupiti. Kontaktiraj vlasnika Organizacije za pomoć." @@ -4222,13 +4222,13 @@ "message": "Sada možeš zatvoriti ovu karticu i nastaviti koristiti proširenje." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Prijava uspješna" }, "thisWindowWillCloseIn5Seconds": { - "message": "This window will automatically close in 5 seconds" + "message": "Ovaj prozor će se automatski zatvoriti za 5 sekundi" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Možeš zatvoriti ovaj prozor" }, "includeAllTeamsFeatures": { "message": "Sve značajke Team, plus:" @@ -4237,7 +4237,7 @@ "message": "Sve značajke Team, plus:" }, "chooseMonthlyOrAnnualBilling": { - "message": "Choose monthly or annual billing" + "message": "Odaberi mjesečnu ili godišnju naplatu" }, "abilityToAddMoreThanNMembers": { "message": "Mogućnost dodavanja više od $COUNT$ članova", @@ -4264,7 +4264,7 @@ "message": "SSO identifikator" }, "ssoIdentifierHintPartOne": { - "message": "Provide this ID to your members to login with SSO. To bypass this step, set up ", + "message": "Dajte ovaj ID svojim članovima za prijavu putem SSO-a. Za zaobilazak ovog koraka, postavi ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Provide this ID to your members to login with SSO. To bypass this step, set up Domain verification'" }, "unlinkSso": { @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Kopiraj vezu" }, "copySendLink": { "message": "Kopiraj vezu na Send", @@ -4805,70 +4805,70 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + "message": "Razvoj, DevOps i IT timovi biraju Bitwarden Secrets Manager za sigurno upravljanje i implementaciju infrastrukture i tajni strojeva." }, "centralizeSecretsManagement": { - "message": "Centralize secrets management." + "message": "Centraliziracija upravljanja tajnama." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Sigurna pohrana i upravljanje tajnama na jednom mjestu kako bi se spriječilo širenje tajni unutar organizacije." }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "Spriječavanje curenja tajni." }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "Zaštita tajni end-to-end enkripcijom. Nema više hard kodiranja tajni ili dijeljenja putem .env datoteka." }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "Povećanje produktivnost programera." }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "Programsko dohvaćanje i implementacija tajni tijekom izvođenja kako bi se programeri mogli usredotočiti na ono što je najvažnije, poput poboljšanja kvalitete koda." }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "Povećanje poslovne sigurnosti." }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "Održavanje strogu kontrole nad strojnim i ljudskim pristupom tajnama uz SSO integracije, zapisnike događaja i rotaciju pristupa." }, "tryItNow": { - "message": "Try it now" + "message": "Isprobajte sada" }, "sendRequest": { - "message": "Send request" + "message": "Pošalji zahtjev" }, "addANote": { - "message": "Add a note" + "message": "Dodaj napomenu" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Više Bitwarden proizvoda" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "Zatraži pristup za Secrets Manager" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "Za isprobavanje Secrets Managera, trebaš dopuštenje svojeg administratora." }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "Zahtjev za pristup Secrets Manageru poslan administratorima e-poštom." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Pozdrav,\n\nMolim pretplatu na Bitwarden Secrets Manager za naš tim. Vaša podrška bi nam puno značila!\n\nBitwarden Secrets Manager je end-to-end kriptirano rješenje za upravljanje tajnama za sigurno pohranjivanje, dijeljenje i implementaciju strojnih vjerodajnica kao što su API ključevi, lozinke za baze podataka i certifikata za autentifikaciju.\n\nSecrets Manager će nam pomoći da:\n\n- poboljšamo sigurnost\n- pojednostavimo poslovanje\n- spriječimo skupa curenja tajnih podataka\n\nZa besplatno probno razdoblje za naš tim, molimo obratite se Bitwardenu.\n\nHvala vam na pomoći!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "Daj članovima pristup do:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "pogledaj i odaberi članove kojima želiš dati pristup do Secrets Managera." }, "openYourOrganizations": { "message": "Open your organization's" }, "usingTheMenuSelect": { - "message": "Using the menu, select" + "message": "Koristeći izbornik, odaberi" }, "toGrantAccessToSelectedMembers": { "message": "to grant access to selected members." @@ -4890,7 +4890,7 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more about Bitwarden Send or sign up to **try it today.**'" }, "sendAccessCreatorIdentifier": { - "message": "Bitwarden korisnik $USER_IDENTIFIER$ je s tobom podijelio", + "message": "Bitwarden korisnik $USER_IDENTIFIER$ je s tobom podijelio/la", "placeholders": { "user_identifier": { "content": "$1", @@ -5020,7 +5020,7 @@ "message": "Administracija oporavka računa" }, "accountRecoveryPolicyDesc": { - "message": "Na temelju metode šifriranja, oporavi račun ako glavna lozinka ili pouzdani uređaji budu zaboravljeni ili izgubljeni." + "message": "Na temelju metode šifriranja, oporavi račune ako je glavna lozinka zaboralvjena ili pouzdani uređaji izgubljen." }, "accountRecoveryPolicyWarning": { "message": "Existing accounts with master passwords will require members to self-enroll before administrators can recover their accounts. Automatic enrollment will turn on account recovery for new members." @@ -5168,7 +5168,7 @@ "message": "Servisni korisnik može pristupiti i upravljati svim organizacijama." }, "providerInviteUserDesc": { - "message": "Pozovi novog korisnika svom davatelju usluga unosom adrese e-pošte Bitwarden računa. Ako nemaju Bitwarden račun, trebati će kreirati novi." + "message": "Pozovi novog korisnika svom davatelju usluga unosom adrese e-pošte Bitwarden računa. Ako nemaju Bitwarden račun, trebati će napraviti novi." }, "joinProvider": { "message": "Pridruži se davatelju usluga" @@ -5195,13 +5195,13 @@ "message": "Stvori novu klijentsku organizaciju koja će biti povezana s tobom kao davateljem usluga. Moći ćeš pristupiti ovoj organizaciji i upravljati njome." }, "newClient": { - "message": "New client" + "message": "Novi klijent" }, "addExistingOrganization": { "message": "Dodaj postojeću organizaciju" }, "addNewOrganization": { - "message": "Add new organization" + "message": "Dodaj novu organizaciju" }, "myProvider": { "message": "Moj davatelj usluga" @@ -5457,7 +5457,7 @@ "message": "Set a unique SP entity ID" }, "spUniqueEntityIdDesc": { - "message": "Generate an identifier that is unique to your organization" + "message": "Generiraj identifikator jedinstven tvojoj organizaciji" }, "idpEntityId": { "message": "ID entiteta" @@ -5628,7 +5628,7 @@ "message": "Potvrdni kôd je obavezan." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "Autentifikacija je otkazana ili je trajala predugo. Molimo pokušaj ponovno." }, "invalidVerificationCode": { "message": "Nevažeći kôd za provjeru" @@ -6846,7 +6846,7 @@ "message": "Odobri pristup zbirkama dodavanjem u ovu grupu." }, "restrictedCollectionAssignmentDesc": { - "message": "You can only assign collections you manage." + "message": "Možeš dodijeliti samo zbirke kojima upravljaš." }, "selectMembers": { "message": "Odaberi članove" @@ -8113,42 +8113,42 @@ "description": "The date header used when a subscription is cancelled." }, "machineAccountsCannotCreate": { - "message": "Machine accounts cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "Strojni računi ne mogu se kreirati u suspendiranim organizacijama. Obrati se vlasniku svoje organizacije za pomoć." }, "machineAccount": { - "message": "Machine account", + "message": "Strojni račun", "description": "A machine user which can be used to automate processes and access secrets in the system." }, "machineAccounts": { - "message": "Machine accounts", + "message": "Strojni računi", "description": "The title for the section that deals with machine accounts." }, "newMachineAccount": { - "message": "New machine account", + "message": "Novi strojni račun", "description": "Title for creating a new machine account." }, "machineAccountsNoItemsMessage": { - "message": "Create a new machine account to get started automating secret access.", + "message": "Stvori novi strojni račun za početak automatizacije tajnog pristupa.", "description": "Message to encourage the user to start creating machine accounts." }, "machineAccountsNoItemsTitle": { - "message": "Nothing to show yet", + "message": "Ništa za prikaz", "description": "Title to indicate that there are no machine accounts to display." }, "deleteMachineAccounts": { - "message": "Delete machine accounts", + "message": "Obriši strojne račune", "description": "Title for the action to delete one or multiple machine accounts." }, "deleteMachineAccount": { - "message": "Delete machine account", + "message": "Obriši strojni račun", "description": "Title for the action to delete a single machine account." }, "viewMachineAccount": { - "message": "View machine account", + "message": "Pogledaj strojni račun", "description": "Action to view the details of a machine account." }, "deleteMachineAccountDialogMessage": { - "message": "Deleting machine account $MACHINE_ACCOUNT$ is permanent and irreversible.", + "message": "Brisanje strojnog računa $MACHINE_ACCOUNT$ je trajno i nepovratno.", "placeholders": { "machine_account": { "content": "$1", @@ -8157,10 +8157,10 @@ } }, "deleteMachineAccountsDialogMessage": { - "message": "Deleting machine accounts is permanent and irreversible." + "message": "Brisanje strojnih računa je trajno i nepovratno." }, "deleteMachineAccountsConfirmMessage": { - "message": "Delete $COUNT$ machine accounts", + "message": "Obriši $COUNT$ strojna/ih računa", "placeholders": { "count": { "content": "$1", @@ -8169,60 +8169,60 @@ } }, "deleteMachineAccountToast": { - "message": "Machine account deleted" + "message": "Strojni račun obrisan" }, "deleteMachineAccountsToast": { - "message": "Machine accounts deleted" + "message": "Strojni računi obrisani" }, "searchMachineAccounts": { - "message": "Search machine accounts", + "message": "Pretraži strojne račune", "description": "Placeholder text for searching machine accounts." }, "editMachineAccount": { - "message": "Edit machine account", + "message": "Uredi strojni račun", "description": "Title for editing a machine account." }, "machineAccountName": { - "message": "Machine account name", + "message": "Naziv strojnog računa", "description": "Label for the name of a machine account" }, "machineAccountCreated": { - "message": "Machine account created", + "message": "Strojni račun stvoren", "description": "Notifies that a new machine account has been created" }, "machineAccountUpdated": { - "message": "Machine account updated", + "message": "Strojni račun ažuriran", "description": "Notifies that a machine account has been updated" }, "projectMachineAccountsDescription": { - "message": "Grant machine accounts access to this project." + "message": "Dozvoli strojnim računima pristup ovom projektu." }, "projectMachineAccountsSelectHint": { - "message": "Type or select machine accounts" + "message": "Upiši ili odaberi strojne račune" }, "projectEmptyMachineAccountAccessPolicies": { - "message": "Add machine accounts to grant access" + "message": "Dodaj strojne račune za dodjelu pristupa" }, "machineAccountPeopleDescription": { - "message": "Grant groups or people access to this machine account." + "message": "Dozvoli grupama ili osobama pristup ovom strojnom računu." }, "machineAccountProjectsDescription": { - "message": "Assign projects to this machine account. " + "message": "Dodijeli projekte ovom strojnom računu. " }, "createMachineAccount": { - "message": "Create a machine account" + "message": "Stvori strojni račun" }, "maPeopleWarningMessage": { - "message": "Removing people from a machine account does not remove the access tokens they created. For security best practice, it is recommended to revoke access tokens created by people removed from a machine account." + "message": "Uklanjanje osoba iz strojnog računa ne uklanja pristupne tokene koje su stvorili. Najbolja sigurnosna praksa preporučuje opozvati pristupne tokene koje su izradile osobe uklonjene iz strojnog računa." }, "smAccessRemovalWarningMaTitle": { - "message": "Remove access to this machine account" + "message": "Ukloni pristup ovom strojnom računu" }, "smAccessRemovalWarningMaMessage": { - "message": "This action will remove your access to the machine account." + "message": "Ovo će ukloniti tvoj pristup strojnom računu." }, "machineAccountsIncluded": { - "message": "$COUNT$ machine accounts included", + "message": "Uključuje $COUNT$ strojnih računa", "placeholders": { "count": { "content": "$1", @@ -8231,7 +8231,7 @@ } }, "additionalMachineAccountCost": { - "message": "$COST$ per month for additional machine accounts", + "message": "Mjesečni trošak za dodatne strojne račune: $COST$", "placeholders": { "cost": { "content": "$1", @@ -8240,10 +8240,10 @@ } }, "additionalMachineAccounts": { - "message": "Additional machine accounts" + "message": "Dodatni strojni računi" }, "includedMachineAccounts": { - "message": "Your plan comes with $COUNT$ machine accounts.", + "message": "Tvoj plan uključuje $COUNT$ strojnih računa.", "placeholders": { "count": { "content": "$1", @@ -8252,7 +8252,7 @@ } }, "addAdditionalMachineAccounts": { - "message": "You can add additional machine accounts for $COST$ per month.", + "message": "Možeš dodati strojni račun za $COST$ mjesečno.", "placeholders": { "cost": { "content": "$1", @@ -8261,19 +8261,19 @@ } }, "limitMachineAccounts": { - "message": "Limit machine accounts (optional)" + "message": "Ograniči strojne račune (opcionalno)" }, "limitMachineAccountsDesc": { - "message": "Set a limit for your machine accounts. Once this limit is reached, you will not be able to create new machine accounts." + "message": "Postavi ograničenje za svoje strojen račune. Kada se ovo ograničenje dosegne, neće biti moguće kreirati nove strojne račune." }, "machineAccountLimit": { - "message": "Machine account limit (optional)" + "message": "Ograničenje strojnih računa (opcionalno)" }, "maxMachineAccountCost": { - "message": "Max potential machine account cost" + "message": "Najveći mogući trošak strojnog računa" }, "machineAccountAccessUpdated": { - "message": "Machine account access updated" + "message": "Ažuriran pristup strojnog računa" }, "restrictedGroupAccessDesc": { "message": "You cannot add yourself to a group." @@ -8415,7 +8415,7 @@ "message": "Manage billing from the Provider Portal" }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Pogledaj stavke u $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -8425,7 +8425,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Natrag na $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -8435,11 +8435,11 @@ } }, "back": { - "message": "Back", + "message": "Natrag", "description": "Button text to navigate back" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Ukloni $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -8449,28 +8449,28 @@ } }, "viewInfo": { - "message": "View info" + "message": "Pogledaj informacije" }, "viewAccess": { - "message": "View access" + "message": "Prikaži pristup" }, "noCollectionsSelected": { - "message": "You have not selected any collections." + "message": "Nije odabrana niti jedna zbirka." }, "updateName": { - "message": "Update name" + "message": "Ažurirajte ime" }, "updatedOrganizationName": { - "message": "Updated organization name" + "message": "Ažurirano ime organizacije" }, "providerPlan": { - "message": "Managed Service Provider" + "message": "Upravljani pružatelj usluga" }, "orgSeats": { - "message": "Organization Seats" + "message": "Organizacijska mjesta" }, "providerDiscount": { - "message": "$AMOUNT$% Discount", + "message": "popust $AMOUNT$%", "placeholders": { "amount": { "content": "$1", @@ -8479,28 +8479,28 @@ } }, "lowKDFIterationsBanner": { - "message": "Low KDF iterations. Increase your iterations to improve the security of your account." + "message": "Niske KDF iteracije. Povećaj svoje iteracije za poboljšanje sigurnost računa." }, "changeKDFSettings": { - "message": "Change KDF settings" + "message": "Promijeni KDF postavke" }, "secureYourInfrastructure": { - "message": "Secure your infrastructure" + "message": "Osiguraj svoju infrastrukturu" }, "protectYourFamilyOrBusiness": { - "message": "Protect your family or business" + "message": "Zaštiti svoju obitelj ii posao" }, "upgradeOrganizationCloseSecurityGaps": { - "message": "Close security gaps with monitoring reports" + "message": "Zatvori sigurnosne nedostatke pomoću izvješća o praćenju" }, "upgradeOrganizationCloseSecurityGapsDesc": { - "message": "Stay ahead of security vulnerabilities by upgrading to a paid plan for enhanced monitoring." + "message": "Budi ispred sigurnosnih ranjivosti nadogradnjom na plaćeni plan za poboljšani nadzor." }, "approveAllRequests": { - "message": "Approve all requests" + "message": "Odobri sve zahtjeve" }, "allLoginRequestsApproved": { - "message": "All login requests approved" + "message": "Svi zahtjevi za prijavu odobreni" }, "payPal": { "message": "PayPal" @@ -8509,59 +8509,59 @@ "message": "Bitcoin" }, "updatedTaxInformation": { - "message": "Updated tax information" + "message": "Ažurirane porezne informacije" }, "unverified": { - "message": "Unverified" + "message": "Nepotvrđeno" }, "verified": { - "message": "Verified" + "message": "Potvrđeno" }, "viewSecret": { - "message": "View secret" + "message": "Pogledaj tajnu" }, "noClients": { - "message": "There are no clients to list" + "message": "Nema klijenata za prikaz" }, "providerBillingEmailHint": { - "message": "This email address will receive all invoices pertaining to this provider", + "message": "Ova adresa e-pošte će primati sve fakture koje se odnose na ovog pružatelja", "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." }, "upgradeOrganizationEnterprise": { - "message": "Identify security risks by auditing member access" + "message": "Identificiraj sigurnosne rizike revizijom pristupa članova" }, "onlyAvailableForEnterpriseOrganization": { - "message": "Quickly view member access across the organization by upgrading to an Enterprise plan." + "message": "Brzo pregledaj pristup članova u cijeloj organizaciji nadogradnjom na Enterprise plan." }, "date": { - "message": "Date" + "message": "Datum" }, "exportClientReport": { - "message": "Export client report" + "message": "Izvezi izvještaj klijenta" }, "memberAccessReport": { - "message": "Member access" + "message": "Pristup člana" }, "memberAccessReportDesc": { - "message": "Ensure members have access to the right credentials and their accounts are secure. Use this report to obtain a CSV of member access and account configurations." + "message": "Uvjeri se da članovi imaju pristup ispravnim vjerodajnicama i da su im računi sigurni. Upotrijebi ovo izvješće za dobivanje CSV-a pristupa članova i konfiguracija računa." }, "memberAccessReportPageDesc": { - "message": "Audit organization member access across groups, collections, and collection items. The CSV export provides a detailed breakdown per member, including information on collection permissions and account configurations." + "message": "Provjeri pristup članova organizacije u grupama, zbirkama i stavkama zbirke. CSV izvoz pruža detaljnu raščlambu po članu, uključujući informacije o dozvolama za prikupljanje i konfiguracijama računa." }, "higherKDFIterations": { - "message": "Higher KDF iterations can help protect your master password from being brute forced by an attacker." + "message": "Veće KDF iteracije mogu pomoći u zaštiti tvoje glavne lozinke od napadača." }, "incrementsOf100,000": { - "message": "increments of 100,000" + "message": "koracima od 100.000" }, "smallIncrements": { - "message": "small increments" + "message": "malim koracima" }, "kdfIterationRecommends": { - "message": "We recommend 600,000 or more" + "message": "Preporučujemo 600.000 ili više" }, "kdfToHighWarningIncreaseInIncrements": { - "message": "For older devices, setting your KDF too high may lead to performance issues. Increase the value in $VALUE$ and test your devices.", + "message": "Previsoko postavljen KDF-a kod starijih uređaja, može dovesti do problema s performansama. Povećaj vrijednost u $VALUE$ i testiraj svoj uređaj.", "placeholders": { "value": { "content": "$1", @@ -8570,31 +8570,31 @@ } }, "providerReinstate": { - "message": " Contact Customer Support to reinstate your subscription." + "message": " Za ponovno uspostavljanje pretplate, obratite se korisničkoj podršci." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Dodijelite grupama ili osobama pristup ovoj tajni. Osobna dopuštenja nadjačat će grupna dopuštenja." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Dodaj osobe ili grupe za dodjelu pristupa ovoj tajni" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Dodijeli pristup ovoj tajni računalnim računima." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Dodaj računalne račune za dodjelu pristupa ovoj tajni" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Ukloni pristup ovoj tajni" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Ovo će ukloniti vaš pristup ovoj tajni." }, "invoice": { - "message": "Invoice" + "message": "Faktura" }, "unassignedSeatsAvailable": { - "message": "You have $SEATS$ unassigned seats available.", + "message": "Imaš dostupno $SEATS$ neraspoređenih mjesta.", "placeholders": { "seats": { "content": "$1", @@ -8604,61 +8604,61 @@ "description": "A message showing how many unassigned seats are available for a provider." }, "contactYourProviderForAdditionalSeats": { - "message": "Contact your provider admin to purchase additional seats." + "message": "Obrati se svom administratoru davatelja za kupnju dodatnih mjesta." }, "open": { - "message": "Open", + "message": "Otvori", "description": "The status of an invoice." }, "uncollectible": { - "message": "Uncollectible", + "message": "Nenaplativo", "description": "The status of an invoice." }, "clientDetails": { - "message": "Client details" + "message": "Detalji klijenta" }, "downloadCSV": { - "message": "Download CSV" + "message": "Preuzmi CSV" }, "monthlySubscriptionUserSeatsMessage": { - "message": "Adjustments to your subscription will result in prorated charges to your billing totals on your next billing period. " + "message": "Prilagodbe pretplate rezultirat će proporcionalnim naknadama ukupnim iznosima naplate u sljedećem obračunskom razdoblju. " }, "annualSubscriptionUserSeatsMessage": { - "message": "Adjustments to your subscription will result in prorated charges on a monthly billing cycle. " + "message": "Prilagodbe pretplate rezultirat će proporcionalnim troškovima u mjesečnom ciklusu naplate. " }, "billingHistoryDescription": { - "message": "Download a CSV to obtain client details for each billing date. Prorated charges are not included in the CSV and may vary from the linked invoice. For the most accurate billing details, refer to your monthly invoices.", + "message": "Preuzmi CSV s podacima o klijentu za svaki datum naplate. Proporcionalni troškovi nisu uključeni u CSV i mogu se razlikovati od povezane fakture. Najtočniji podaci o naplati mogu se pronaći u mjesečnim fakturama.", "description": "A paragraph on the Billing History page of the Provider Portal letting users know they can download a CSV report for their invoices that does not include prorations." }, "noInvoicesToList": { - "message": "There are no invoices to list", + "message": "Nema faktura za prikaz", "description": "A paragraph on the Billing History page of the Provider Portal letting users know they can download a CSV report for their invoices that does not include prorations." }, "providerClientVaultPrivacyNotification": { - "message": "Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions,", + "message": "Napomena: Kasnije ovog mjeseca, privatnost klijentskog trezora bit će poboljšana i članovi pružatelja više neće imati izravan pristup stavkama klijentskog trezora. Za pitanja", "description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions, please contact Bitwarden support'." }, "contactBitwardenSupport": { - "message": "contact Bitwarden support.", + "message": "kontaktiraj Bitwarden podršku.", "description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions, please contact Bitwarden support'. 'Bitwarden' should not be translated" }, "sponsored": { - "message": "Sponsored" + "message": "Sponzorirano" }, "licenseAndBillingManagementDesc": { - "message": "After making updates in the Bitwarden cloud server, upload your license file to apply the most recent changes." + "message": "Nakon ažuriranja Bitwarden poslužitelja u oblaku, prenesite datoteku licence za primjenu najnovijih izmjena." }, "addToFolder": { - "message": "Add to folder" + "message": "Dodaj u mapu" }, "selectFolder": { - "message": "Select folder" + "message": "Odaberi mapu" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 stavka će biti trajno prenesena u odabranu organizaciju. Više nećeš posjedovati ovu stavku." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ stavke/i će biti trajno prenesene u odabranu organizaciju. Više nećeš posjedovati ove stavke.", "placeholders": { "personal_items_count": { "content": "$1", @@ -8667,7 +8667,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 stavka će biti trajno prenesena u $ORG$. Više nećeš posjedovati ovu stavku.", "placeholders": { "org": { "content": "$1", @@ -8676,7 +8676,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ stavke/i će biti trajno prenesene u $ORG$. Više nećeš posjedovati ove stavke.", "placeholders": { "personal_items_count": { "content": "$1", @@ -8689,9 +8689,9 @@ } }, "data": { - "message": "Data" + "message": "Podaci" }, "purchasedSeatsRemoved": { - "message": "purchased seats removed" + "message": "kupljenih mjesta uklonjeno" } } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 5dbde9079ae..32fb10d4d81 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Hivatkozás másolása" }, "copySendLink": { "message": "Send hivatkozás másolása", diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 9148f85ecb1..add70a545f5 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -4817,61 +4817,61 @@ "message": "シークレットの漏洩を防ぎます。" }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "エンドツーエンド暗号化でシークレットを保護します。シークレットハードコーディングや .env ファイルでの共有はもう必要ありません。" }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "開発者の生産性を高めます。" }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "開発者がコードの品質を向上させるなど最も重要なことに集中できるように、プログラム実行時にシークレットを取得およびデプロイします。" }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "ビジネスの安全を強化します。" }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "SSO 統合、イベントログ、アクセスローテーションを使用して、マシンと人間のシークレットへのアクセスを厳密に制御します。" }, "tryItNow": { - "message": "Try it now" + "message": "今すぐ試す" }, "sendRequest": { - "message": "Send request" + "message": "リクエストを送信" }, "addANote": { - "message": "Add a note" + "message": "メモを追加" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Bitwarden シークレットマネージャー" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Bitwarden の他の製品" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "シークレットマネージャーへのアクセスを要求する" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "シークレットマネージャーを試すには管理者からの承認が必要です。" }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "シークレットマネージャーのアクセスリクエストメールを管理者に送信しました。" }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "お疲れ様です。\n\nチームでの Bitwarden シークレットマネージャーのサブスクリプション契約を検討していただけないでしょうか。\n\nBitwarden シークレットマネージャーは、API キー、データベースパスワード、認証証明書などのマシン認証情報を安全に保管、共有、デプロイするためのエンドツーエンドの暗号化シークレット管理ソリューションです。\n\n・セキュリティ強化\n・操作の簡素化\n・シークレット流出防止\nといった観点で効果的だと考えております。\n\nBitwarden に連絡いただければ無料お試しも可能です。\n\nご検討よろしくお願いいたします。" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "メンバーにアクセスを許可する:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "一覧を表示して、シークレットマネージャーへのアクセスを許可したいメンバーを選択してください。" }, "openYourOrganizations": { - "message": "Open your organization's" + "message": "組織の" }, "usingTheMenuSelect": { - "message": "Using the menu, select" + "message": "メニューを使用して、" }, "toGrantAccessToSelectedMembers": { - "message": "to grant access to selected members." + "message": "をクリックすると選択したメンバーへのアクセスを許可します。" }, "sendVaultCardTryItNow": { "message": "試してみてください", diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index b072abd88b5..08accba33ef 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -3460,7 +3460,7 @@ "message": "Tu esi uzaicināts pievienoties augstāk norādītajai apvienībai. Lai to pieņemtu, jāpiesakās vai jāizveido jauns Bitwarden konts." }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Pabeigt pievienošanos šai apvienībai ar galvenās paroles iestatīšanu." }, "inviteAccepted": { "message": "Uzaicinājums pieņemts" @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Ievietot saiti starpliktuvē" }, "copySendLink": { "message": "Ievietot Send saiti starpliktuvē", @@ -4805,73 +4805,73 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + "message": "Izstrādes, DevOps un IT komandas izvēlas Bitwarden noslēpumu pārvaldnieku, lai droši pārvaldītu un izvietotu savus infrastruktūras un mašīnu noslēpumus." }, "centralizeSecretsManagement": { - "message": "Centralize secrets management." + "message": "Noslēpumu pārvaldības centralizēšana." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Noslēpumu droša uzglabāšana un pārvaldīšana vienā vietā, lai apvienībā novērstu noslēpumu izkliedētību." }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "Noslēpumu noplūdes novēršana." }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "Noslēpumu aizsargāšana ar pilnīgu šifrēšanu. Vairs nekādu noslēpumu kodā vai kopīgošana ar .env datnēm." }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "Izstrādātāju produktivitātes uzlabošana." }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "Noslēpumu programmatiska izgūšana un izvietošana izpildlaikā, tādējādi izstrādātāji var pievērsties svarīgākajam, piemēram, koda kvalitātes uzlabošanai." }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "Uzņēmējdarbības drošības stiprināšana." }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "Ciešas pārraudzības pār mašīnu un cilvēku piekļuvi noslēpumiem uzturēšana ar SSO integrācijām, notikumu žurnāliem un piekļuves maiņa." }, "tryItNow": { - "message": "Try it now" + "message": "Izmēģināt tagad" }, "sendRequest": { - "message": "Send request" + "message": "Nosūtīt pieprasījumu" }, "addANote": { - "message": "Add a note" + "message": "Pievienot piezīmi" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Bitwarden noslēpumu pārvaldnieks" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Vairāk izstrādājumu no Bitwarden" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "Pieprasīt piekļuvi Noslēpumu pārvaldniekam" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "Ir nepieciešams apstiprinājums no pārvaldītāja, lai izmēģinātu Noslēpumu pārvaldnieku." }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "Piekļuves pieprasījuma Noslēpumu pārvaldniekam e-pasta ziņojumus ir nosūtīts pārvaldītājiem." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Sveiki!\n\nEs lūdzu Bitwarden noslēpumu pārvaldnieka abonementu mūsu komandai. Jūsu atbalsts būs ļoti nozīmīgs.\n\nBitwarden noslēpumu pārvaldnieks ir pilnībā šifrēts noslēpumu pārvaldības risinājumus tādu mašīnu piekļuves datu kā API atslēgu, datubāžu paroļu un autentifikācijas sertifikātu drošai uzglabāšanai, kopīgošanai un izvietošanai.\n\nNoslēpumu pārvaldnieks palīdzēs mums:\n\n- uzlabot drošību;\n- pilnveidot darbības;\n- novērst dārgas noslēpumu noplūdes.\n\nLai pieprasītu bezmaksas izmēģinājumu mūsu komandai, lūgums vērsties pie Bitwarden.\n\nPaldies par palīdzību!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "Piešķirt dalībniekiem piekļuvi:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "skatīt un atlasīt dalībniekus, kuriem piešķirt piekļuvi Noslēpumu pārvaldniekam." }, "openYourOrganizations": { - "message": "Open your organization's" + "message": "Jāatver savas apvienības" }, "usingTheMenuSelect": { - "message": "Using the menu, select" + "message": "Izvēlnē jāatlasa" }, "toGrantAccessToSelectedMembers": { - "message": "to grant access to selected members." + "message": ", lai piešķirtu piekļuvi atlasītajiem dalībniekiem." }, "sendVaultCardTryItNow": { "message": "izmēģināt tagad", diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index e0cb3aab0e5..6580228dee0 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -1507,7 +1507,7 @@ "message": "Chyba pri dešifrovaní exportovaného súboru. Váš šifrovací kľúč sa nezhoduje so šifrovacím kľúčom použitým pri exporte údajov." }, "destination": { - "message": "Destination" + "message": "Cieľ" }, "learnAboutImportOptions": { "message": "Zistiť viac o možnostiach importu" @@ -3460,7 +3460,7 @@ "message": "Obdržali ste pozvánku do vyššie menovanej Organizácie. Ak chcete pozvánku prijať, musíte sa prihlásiť alebo si vytvoriť nový Bitwarden účet." }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Dokončite pripojenie k tejto organizácii nastavením hlavného hesla." }, "inviteAccepted": { "message": "Pozvánka prijatá" @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Kopírovať odkaz" }, "copySendLink": { "message": "Kopírovať odkaz na Send", @@ -4805,73 +4805,73 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + "message": "Vývojari, DevOps a IT tímy si vyberajú Bitwarden Secrets Manager na bezpečnú správu a nasadenie tajomstiev pre infraštruktúru a zariadenia." }, "centralizeSecretsManagement": { - "message": "Centralize secrets management." + "message": "Centralizujte správu tajomstiev." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Bezpečne ukladajte a spravujte tajomstvá na jednom mieste a zabráňte rozptýleniu tajomstiev v celej organizácii." }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "Zabráňte úniku tajomstiev." }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "Chráňte tajomstvá pomocou end-to-end šifrovania. Už žiadne vkladanie tajomstiev do kódu alebo zdieľanie prostredníctvom súborov .env." }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "Zlepšite vývojársku produktivitu." }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "Programovo získavajte a nasadzujte tajomstvá za behu, aby sa vývojári mohli sústrediť na to najdôležitejšie, napríklad na zlepšovanie kvality kódu." }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "Posilnite bezpečnosť spoločnosti." }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "Udržujte prísnu kontrolu nad prístupom strojov a ľudí k tajomstvám pomocou integrácie SSO, protokolov udalostí a rotácie prístupu." }, "tryItNow": { - "message": "Try it now" + "message": "Vyskúšať teraz" }, "sendRequest": { - "message": "Send request" + "message": "Odoslať žiadosť" }, "addANote": { - "message": "Add a note" + "message": "Pridať poznámku" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Viac produktov od spoločnosti Bitwarden" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "Požiadať o prístup k Secrets Manager" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "Aby ste mohli vyskúšať Secrets Manager, potrebujete povolenie od vášho správcu." }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "Požiadavka na Secrets Manager odoslaná vaším správcom." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Ahoj,\n\nŽiadam o predplatné programu Bitwarden Secrets Manager pre náš tím. Veľmi by sme ocenili Vašu podporu.\n\nBitwarden Secrets Manager je komplexné šifrované riešenie na správu tajomstiev a na bezpečné ukladanie, zdieľanie a nasadzovanie strojových poverení, ako sú kľúče API, heslá do databáz a autentifikačné certifikáty.\n\nSecrets Manager nám pomôže:\n\n- Zlepšiť bezpečnosť\n- Zefektívniť prevádzku\n- Zabrániť nákladným únikom tajomstiev\n\nAk chcete požiadať o bezplatnú skúšobnú verziu pre náš tím, obráťte sa na spoločnosť Bitwarden.\n\nĎakujeme za vašu pomoc!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "Poskytnúť členom prístup k:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "zobrazte a vyberte členov ktorým chcete umožniť prístup k Secrets Manager." }, "openYourOrganizations": { - "message": "Open your organization's" + "message": "Otvorte organizáciu" }, "usingTheMenuSelect": { - "message": "Using the menu, select" + "message": "Pomocou menu vyberte" }, "toGrantAccessToSelectedMembers": { - "message": "to grant access to selected members." + "message": "aby ste povolili prístup vybraným členom." }, "sendVaultCardTryItNow": { "message": "to skúste teraz", @@ -7997,10 +7997,10 @@ "message": "Prideliť k týmto zbierkam" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Položku si budú môcť pozrieť len členovia organizácie s prístupom k týmto zbierkam." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Položky si budú môcť pozrieť len členovia organizácie s prístupom k týmto zbierkam." }, "selectCollectionsToAssign": { "message": "Vyberte zbierky na pridelenie" @@ -8689,7 +8689,7 @@ } }, "data": { - "message": "Data" + "message": "Údaje" }, "purchasedSeatsRemoved": { "message": "zakúpené sedenia boli odstránené" diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index b6cd1f87616..85fe714a1f4 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -571,7 +571,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Елементи переміщено до $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -580,7 +580,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Елемент переміщено до $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -1507,7 +1507,7 @@ "message": "Помилка розшифрування експортованого файлу. Ваш ключ шифрування відрізняється від ключа, використаного для експортування даних." }, "destination": { - "message": "Destination" + "message": "Призначення" }, "learnAboutImportOptions": { "message": "Дізнайтеся про параметри імпорту" @@ -3460,7 +3460,7 @@ "message": "Вас було запрошено приєднатися до зазначеної вгорі організації. Щоб підтвердити запрошення, вам необхідно увійти в обліковий запис Bitwarden, або створити його." }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Завершіть приєднання до цієї організації, встановивши головний пароль." }, "inviteAccepted": { "message": "Запрошення прийнято" @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "Копіювати посилання" }, "copySendLink": { "message": "Копіювати посилання відправлення", @@ -4805,73 +4805,73 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "Development, DevOps, and IT teams choose Bitwarden Secrets Manager to securely manage and deploy their infrastructure and machine secrets." + "message": "Команди розробників, DevOps та IT-спеціалісти обирають Менеджер секретів Bitwarden для безпечного керування і розгортання інфраструктурних і машинних секретів." }, "centralizeSecretsManagement": { - "message": "Centralize secrets management." + "message": "Централізуйте керування секретами." }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "Безпечно зберігайте та керуйте секретами в одному місці, щоб запобігти неналежному розповсюдженню в організації." }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "Запобігайте витоку секретів." }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "Захистіть секрети за допомогою наскрізного шифрування. Більше не потрібно кодувати секрети чи ділитися ними за допомогою файлів .env." }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "Підвищте продуктивність розробників." }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "Програмовано отримуйте та розгортайте секрети, щоб розробники могли зосередитися на найважливішому, як-от вдосконалення якості коду." }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "Посильте безпеку бізнесу." }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "Надійно контролюйте доступ машин і людей до секретів за допомогою інтеграції SSO, журналів подій та оновлення дозволів на доступ." }, "tryItNow": { - "message": "Try it now" + "message": "Спробувати зараз" }, "sendRequest": { - "message": "Send request" + "message": "Надіслати запит" }, "addANote": { - "message": "Add a note" + "message": "Додати нотатку" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Менеджер секретів Bitwarden" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "Інші продукти від Bitwarden" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "Запитати доступ до менеджера секретів" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "Щоб спробувати менеджер секретів, необхідне схвалення вашого адміністратора." }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "Електронний лист із запитом на доступ до менеджера секретів надіслано адміністраторам." }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "Вітаю!\n\nПрошу надати передплату на Менеджер секретів Bitwarden для нашої команди. Ваша підтримка дуже важлива для нас!\n\nМенеджер секретів Bitwarden – це рішення з наскрізним шифруванням для керування секретами, яке дає змогу надійно зберігати, ділитися та розгортати машинні облікові дані, як-от ключі API, паролі баз даних і сертифікати автентифікації.\n\nЗа допомогою менеджера секретів ми зможемо:\n\n- Вдосконалити безпеку\n- Підвищити продуктивність операцій\n- Запобігти витоку секретів\n\nЩоб надіслати запит на безплатний пробний період для нашої команди, зверніться до Bitwarden.\n\nДякую за допомогу!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "Надати доступ учасникам:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "перегляньте й виберіть учасників, яким ви хочете надати доступ до менеджера секретів." }, "openYourOrganizations": { - "message": "Open your organization's" + "message": "Відкрийте" }, "usingTheMenuSelect": { - "message": "Using the menu, select" + "message": "За допомогою меню виберіть" }, "toGrantAccessToSelectedMembers": { - "message": "to grant access to selected members." + "message": "вашої організації, щоб надати доступ вибраним учасникам." }, "sendVaultCardTryItNow": { "message": "спробуйте", @@ -7997,10 +7997,10 @@ "message": "Призначити до цих збірок" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Лише учасники організації з доступом до цих збірок зможуть переглядати запис." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Лише учасники організації з доступом до цих збірок зможуть переглядати записи." }, "selectCollectionsToAssign": { "message": "Оберіть збірки для призначення" @@ -8655,10 +8655,10 @@ "message": "Вибрати теку" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "1 елемент буде остаточно перенесено до вибраної організації. Ви більше не будете власником цього елемента." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ елементи буде остаточно перенесено до вибраної організації. Ви більше не будете власником цих елементів.", "placeholders": { "personal_items_count": { "content": "$1", @@ -8667,7 +8667,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "1 елемент буде остаточно перенесено до $ORG$. Ви більше не будете власником цього елемента.", "placeholders": { "org": { "content": "$1", @@ -8676,7 +8676,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ елементи буде остаточно перенесено до $ORG$. Ви більше не будете власником цих елементів.", "placeholders": { "personal_items_count": { "content": "$1", @@ -8689,7 +8689,7 @@ } }, "data": { - "message": "Data" + "message": "Дані" }, "purchasedSeatsRemoved": { "message": "куплених місць вилучено" diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index b248fb576b4..590ec9507aa 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -1507,7 +1507,7 @@ "message": "解密导出的文件时出错。您的加密密钥与导出数据时使用的加密密钥不匹配。" }, "destination": { - "message": "Destination" + "message": "目的地" }, "learnAboutImportOptions": { "message": "了解您的导入选项" @@ -3587,10 +3587,10 @@ "message": "验证银行账户" }, "verifyBankAccountDesc": { - "message": "我们已将两笔小额转账存入您的银行账户(将会在 1-2 个工作日到账)。输入这些金额来验证银行账户。" + "message": "我们已向您的银行账户存入了两笔小额转账(可能需要 1-2 个工作日到账)。输入这些金额以验证银行账户。" }, "verifyBankAccountInitialDesc": { - "message": "只有美国用户才能使用银行账户付款。您需要验证自己的银行账户。我们将在 1-2 个工作日内进行两笔小额转账,在组织的计费页面输入这些金额来验证银行账户。" + "message": "使用银行账户付款仅对美国用户开放。您将被要求验证您的银行账户。我们将在 1-2 个工作日内进行两笔小额转账,请在组织的计费页面输入这些金额以验证银行账户。" }, "verifyBankAccountFailureWarning": { "message": "验证银行账户失败将会错过支付,您的订阅将失效。" @@ -4387,7 +4387,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copyLink": { - "message": "Copy link" + "message": "复制链接" }, "copySendLink": { "message": "复制 Send 链接", @@ -4805,73 +4805,73 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more, see how it works, **or** try it now.'" }, "developmentDevOpsAndITTeamsChooseBWSecret": { - "message": "开发 DevOps 和 IT 团队选择 Bitwarden 机密管理器来安全管理和部署他们的基础设施和机器秘密。" + "message": "开发、DevOps 和 IT 团队选择 Bitwarden 机密管理器来安全地管理和部署他们的基础设施和机器机密。" }, "centralizeSecretsManagement": { - "message": "集中管理秘密。" + "message": "集中管理机密。" }, "centralizeSecretsManagementDescription": { - "message": "Securely store and manage secrets in one location to prevent secret sprawl across your organization." + "message": "在一个位置安全地存储和管理机密,以防止机密扩散到您的组织。" }, "preventSecretLeaks": { - "message": "Prevent secret leaks." + "message": "防止机密遭泄漏。" }, "preventSecretLeaksDescription": { - "message": "Protect secrets with end-to-end encryption. No more hard coding secrets or sharing through .env files." + "message": "使用端到端加密保护机密。而不再需要硬编码机密或通过 .env 文件分享机密。" }, "enhanceDeveloperProductivity": { - "message": "Enhance developer productivity." + "message": "提高开发人员的生产力。" }, "enhanceDeveloperProductivityDescription": { - "message": "Programmatically retrieve and deploy secrets at runtime so developers can focus on what matters most, like improving code quality." + "message": "程序化地在运行时检索和部署机密,使开发人员可以专注于最重要的事情,例如提高代码质量。" }, "strengthenBusinessSecurity": { - "message": "Strengthen business security." + "message": "加强企业安全。" }, "strengthenBusinessSecurityDescription": { - "message": "Maintain tight control over machine and human access to secrets with SSO integrations, event logs, and access rotation." + "message": "通过 SSO 集成、事件日志和访问轮换,保持机器和人类对机密访问权限的严格控制。" }, "tryItNow": { - "message": "Try it now" + "message": "立即试用" }, "sendRequest": { - "message": "Send request" + "message": "发送请求" }, "addANote": { - "message": "Add a note" + "message": "添加备注" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Bitwarden 机密管理器" }, "moreProductsFromBitwarden": { - "message": "More products from Bitwarden" + "message": "更多来自 Bitwarden 的产品" }, "requestAccessToSecretsManager": { - "message": "Request access to Secrets Manager" + "message": "请求访问机密管理器" }, "youNeedApprovalFromYourAdminToTrySecretsManager": { - "message": "You need approval from your administrator to try Secrets Manager." + "message": "您需要管理员的批准才能试用机密管理器。" }, "smAccessRequestEmailSent": { - "message": "Access request for secrets manager email sent to admins." + "message": "对机密管理器的访问请求电子邮件已发送给管理员。" }, "requestAccessSMDefaultEmailContent": { - "message": "Hi,\n\nI am requesting a subscription to Bitwarden Secrets Manager for our team. Your support would mean a great deal!\n\nBitwarden Secrets Manager is an end-to-end encrypted secrets management solution for securely storing, sharing, and deploying machine credentials like API keys, database passwords, and authentication certificates.\n\nSecrets Manager will help us to:\n\n- Improve security\n- Streamline operations\n- Prevent costly secret leaks\n\nTo request a free trial for our team, please reach out to Bitwarden.\n\nThank you for your help!" + "message": "您好,\n\n我请求为我们的团队订阅 Bitwarden Secrets Manager。您的支持对我们来说意义重大!\n\nBitwarden Secrets Manager 是一个端到端加密的机密管理解决方案,用于安全地存储、共享和部署机器凭证,如 API 密钥、数据库密码和身份验证证书。\n\nSecrets Manager 将帮助我们:\n\n- 提高安全性\n- 精简操作\n- 防止昂贵的机密遭泄漏\n\n要为我们的团队申请免费试用,请联系 Bitwarden。\n\n感谢您的帮助!" }, "giveMembersAccess": { - "message": "Give members access:" + "message": "授予成员访问权限:" }, "viewAndSelectTheMembers": { - "message": "view and select the members you want to give access to Secrets Manager." + "message": "查看并选择您想要授予机密管理器访问权限的成员。" }, "openYourOrganizations": { - "message": "Open your organization's" + "message": "打开您的组织的" }, "usingTheMenuSelect": { - "message": "Using the menu, select" + "message": "使用菜单,选择" }, "toGrantAccessToSelectedMembers": { - "message": "to grant access to selected members." + "message": "以授予所选成员的访问权限。" }, "sendVaultCardTryItNow": { "message": "立即体验", @@ -8689,7 +8689,7 @@ } }, "data": { - "message": "Data" + "message": "数据" }, "purchasedSeatsRemoved": { "message": "购买的席位已移除" From c91f9146da55f007c8d1d83071e70b611018db39 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:21:21 -0400 Subject: [PATCH 18/46] [PM-9978] Add State Logging Options (#10251) * Add `DebugOptions` to Definitions * Respect Debug Options * Configure DI --- .../browser/src/background/main.background.ts | 6 +- apps/cli/src/service-container.ts | 6 +- apps/desktop/src/main.ts | 6 +- .../src/services/jslib-services.module.ts | 4 +- .../default-active-user-state.spec.ts | 3 + .../default-global-state.provider.ts | 12 ++- .../default-global-state.spec.ts | 5 +- .../implementations/default-global-state.ts | 4 +- .../default-single-user-state.provider.ts | 3 + .../default-single-user-state.spec.ts | 62 +++++++++++++ .../default-single-user-state.ts | 4 +- .../specific-state.provider.spec.ts | 5 +- .../state/implementations/state-base.ts | 22 +++++ .../src/platform/state/key-definition.spec.ts | 93 ++++++++++++++++++- .../src/platform/state/key-definition.ts | 36 +++++++ .../src/platform/state/user-key-definition.ts | 14 ++- 16 files changed, 272 insertions(+), 13 deletions(-) diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index f49fa3e7da9..21b02564e38 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -482,7 +482,10 @@ export default class MainBackground { this.largeObjectMemoryStorageForStateProviders, ); - this.globalStateProvider = new DefaultGlobalStateProvider(storageServiceProvider); + this.globalStateProvider = new DefaultGlobalStateProvider( + storageServiceProvider, + this.logService, + ); const stateEventRegistrarService = new StateEventRegistrarService( this.globalStateProvider, @@ -505,6 +508,7 @@ export default class MainBackground { this.singleUserStateProvider = new DefaultSingleUserStateProvider( storageServiceProvider, stateEventRegistrarService, + this.logService, ); this.accountService = new AccountServiceImplementation( this.messagingService, diff --git a/apps/cli/src/service-container.ts b/apps/cli/src/service-container.ts index f9bff5c6d04..8ee99fa2039 100644 --- a/apps/cli/src/service-container.ts +++ b/apps/cli/src/service-container.ts @@ -291,7 +291,10 @@ export class ServiceContainer { this.memoryStorageForStateProviders, ); - this.globalStateProvider = new DefaultGlobalStateProvider(storageServiceProvider); + this.globalStateProvider = new DefaultGlobalStateProvider( + storageServiceProvider, + this.logService, + ); const stateEventRegistrarService = new StateEventRegistrarService( this.globalStateProvider, @@ -308,6 +311,7 @@ export class ServiceContainer { this.singleUserStateProvider = new DefaultSingleUserStateProvider( storageServiceProvider, stateEventRegistrarService, + this.logService, ); this.messagingService = MessageSender.EMPTY; diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index ef7ee37ccd6..762c755485a 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -109,7 +109,10 @@ export class Main { this.storageService, this.memoryStorageForStateProviders, ); - const globalStateProvider = new DefaultGlobalStateProvider(storageServiceProvider); + const globalStateProvider = new DefaultGlobalStateProvider( + storageServiceProvider, + this.logService, + ); this.i18nService = new I18nMainService("en", "./locales/", globalStateProvider); @@ -130,6 +133,7 @@ export class Main { const singleUserStateProvider = new DefaultSingleUserStateProvider( storageServiceProvider, stateEventRegistrarService, + this.logService, ); const activeUserStateProvider = new DefaultActiveUserStateProvider( diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index a0fec2ad05f..5427c586af1 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1119,7 +1119,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: GlobalStateProvider, useClass: DefaultGlobalStateProvider, - deps: [StorageServiceProvider], + deps: [StorageServiceProvider, LogService], }), safeProvider({ provide: ActiveUserStateProvider, @@ -1129,7 +1129,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: SingleUserStateProvider, useClass: DefaultSingleUserStateProvider, - deps: [StorageServiceProvider, StateEventRegistrarService], + deps: [StorageServiceProvider, StateEventRegistrarService, LogService], }), safeProvider({ provide: DerivedStateProvider, diff --git a/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts b/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts index c652136a0d1..6df34e558a3 100644 --- a/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts +++ b/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts @@ -10,6 +10,7 @@ import { awaitAsync, trackEmissions } from "../../../../spec"; import { FakeStorageService } from "../../../../spec/fake-storage.service"; import { AccountInfo } from "../../../auth/abstractions/account.service"; import { UserId } from "../../../types/guid"; +import { LogService } from "../../abstractions/log.service"; import { StorageServiceProvider } from "../../services/storage-service.provider"; import { StateDefinition } from "../state-definition"; import { StateEventRegistrarService } from "../state-event-registrar.service"; @@ -45,6 +46,7 @@ describe("DefaultActiveUserState", () => { let diskStorageService: FakeStorageService; const storageServiceProvider = mock(); const stateEventRegistrarService = mock(); + const logService = mock(); let activeAccountSubject: BehaviorSubject<{ id: UserId } & AccountInfo>; let singleUserStateProvider: DefaultSingleUserStateProvider; @@ -58,6 +60,7 @@ describe("DefaultActiveUserState", () => { singleUserStateProvider = new DefaultSingleUserStateProvider( storageServiceProvider, stateEventRegistrarService, + logService, ); activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>(undefined); diff --git a/libs/common/src/platform/state/implementations/default-global-state.provider.ts b/libs/common/src/platform/state/implementations/default-global-state.provider.ts index 42adf3b9766..03bca3f6d54 100644 --- a/libs/common/src/platform/state/implementations/default-global-state.provider.ts +++ b/libs/common/src/platform/state/implementations/default-global-state.provider.ts @@ -1,3 +1,4 @@ +import { LogService } from "../../abstractions/log.service"; import { StorageServiceProvider } from "../../services/storage-service.provider"; import { GlobalState } from "../global-state"; import { GlobalStateProvider } from "../global-state.provider"; @@ -8,7 +9,10 @@ import { DefaultGlobalState } from "./default-global-state"; export class DefaultGlobalStateProvider implements GlobalStateProvider { private globalStateCache: Record> = {}; - constructor(private storageServiceProvider: StorageServiceProvider) {} + constructor( + private storageServiceProvider: StorageServiceProvider, + private readonly logService: LogService, + ) {} get(keyDefinition: KeyDefinition): GlobalState { const [location, storageService] = this.storageServiceProvider.get( @@ -23,7 +27,11 @@ export class DefaultGlobalStateProvider implements GlobalStateProvider { return existingGlobalState as DefaultGlobalState; } - const newGlobalState = new DefaultGlobalState(keyDefinition, storageService); + const newGlobalState = new DefaultGlobalState( + keyDefinition, + storageService, + this.logService, + ); this.globalStateCache[cacheKey] = newGlobalState; return newGlobalState; diff --git a/libs/common/src/platform/state/implementations/default-global-state.spec.ts b/libs/common/src/platform/state/implementations/default-global-state.spec.ts index f592d35ab55..0f8e7028af4 100644 --- a/libs/common/src/platform/state/implementations/default-global-state.spec.ts +++ b/libs/common/src/platform/state/implementations/default-global-state.spec.ts @@ -3,11 +3,13 @@ * @jest-environment ../shared/test.environment.ts */ +import { mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; import { Jsonify } from "type-fest"; import { trackEmissions, awaitAsync } from "../../../../spec"; import { FakeStorageService } from "../../../../spec/fake-storage.service"; +import { LogService } from "../../abstractions/log.service"; import { KeyDefinition, globalKeyBuilder } from "../key-definition"; import { StateDefinition } from "../state-definition"; @@ -38,11 +40,12 @@ const globalKey = globalKeyBuilder(testKeyDefinition); describe("DefaultGlobalState", () => { let diskStorageService: FakeStorageService; let globalState: DefaultGlobalState; + const logService = mock(); const newData = { date: new Date() }; beforeEach(() => { diskStorageService = new FakeStorageService(); - globalState = new DefaultGlobalState(testKeyDefinition, diskStorageService); + globalState = new DefaultGlobalState(testKeyDefinition, diskStorageService, logService); }); afterEach(() => { diff --git a/libs/common/src/platform/state/implementations/default-global-state.ts b/libs/common/src/platform/state/implementations/default-global-state.ts index f44d5e26c6e..c88e9303c8e 100644 --- a/libs/common/src/platform/state/implementations/default-global-state.ts +++ b/libs/common/src/platform/state/implementations/default-global-state.ts @@ -1,3 +1,4 @@ +import { LogService } from "../../abstractions/log.service"; import { AbstractStorageService, ObservableStorageService, @@ -14,7 +15,8 @@ export class DefaultGlobalState constructor( keyDefinition: KeyDefinition, chosenLocation: AbstractStorageService & ObservableStorageService, + logService: LogService, ) { - super(globalKeyBuilder(keyDefinition), chosenLocation, keyDefinition); + super(globalKeyBuilder(keyDefinition), chosenLocation, keyDefinition, logService); } } diff --git a/libs/common/src/platform/state/implementations/default-single-user-state.provider.ts b/libs/common/src/platform/state/implementations/default-single-user-state.provider.ts index a913bb02bdc..c63962f1cc7 100644 --- a/libs/common/src/platform/state/implementations/default-single-user-state.provider.ts +++ b/libs/common/src/platform/state/implementations/default-single-user-state.provider.ts @@ -1,4 +1,5 @@ import { UserId } from "../../../types/guid"; +import { LogService } from "../../abstractions/log.service"; import { StorageServiceProvider } from "../../services/storage-service.provider"; import { StateEventRegistrarService } from "../state-event-registrar.service"; import { UserKeyDefinition } from "../user-key-definition"; @@ -13,6 +14,7 @@ export class DefaultSingleUserStateProvider implements SingleUserStateProvider { constructor( private readonly storageServiceProvider: StorageServiceProvider, private readonly stateEventRegistrarService: StateEventRegistrarService, + private readonly logService: LogService, ) {} get(userId: UserId, keyDefinition: UserKeyDefinition): SingleUserState { @@ -33,6 +35,7 @@ export class DefaultSingleUserStateProvider implements SingleUserStateProvider { keyDefinition, storageService, this.stateEventRegistrarService, + this.logService, ); this.cache[cacheKey] = newUserState; return newUserState; diff --git a/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts b/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts index 3f51828a59f..0a98c55970b 100644 --- a/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts +++ b/libs/common/src/platform/state/implementations/default-single-user-state.spec.ts @@ -10,6 +10,7 @@ import { Jsonify } from "type-fest"; import { trackEmissions, awaitAsync } from "../../../../spec"; import { FakeStorageService } from "../../../../spec/fake-storage.service"; import { UserId } from "../../../types/guid"; +import { LogService } from "../../abstractions/log.service"; import { Utils } from "../../misc/utils"; import { StateDefinition } from "../state-definition"; import { StateEventRegistrarService } from "../state-event-registrar.service"; @@ -45,6 +46,7 @@ describe("DefaultSingleUserState", () => { let diskStorageService: FakeStorageService; let userState: DefaultSingleUserState; const stateEventRegistrarService = mock(); + const logService = mock(); const newData = { date: new Date() }; beforeEach(() => { @@ -54,6 +56,7 @@ describe("DefaultSingleUserState", () => { testKeyDefinition, diskStorageService, stateEventRegistrarService, + logService, ); }); @@ -108,15 +111,23 @@ describe("DefaultSingleUserState", () => { cleanupDelayMs: 0, deserializer: TestState.fromJSON, clearOn: [], + debug: { + enableRetrievalLogging: true, + }, }), diskStorageService, stateEventRegistrarService, + logService, ); await firstValueFrom(state.state$); await firstValueFrom(state.state$); expect(diskStorageService.mock.get).toHaveBeenCalledTimes(2); + expect(logService.info).toHaveBeenCalledTimes(2); + expect(logService.info).toHaveBeenCalledWith( + `Retrieving 'user_${userId}_fake_test' from storage, value is null`, + ); }); }); @@ -324,6 +335,57 @@ describe("DefaultSingleUserState", () => { expect(stateEventRegistrarService.registerEvents).not.toHaveBeenCalled(); }, ); + + const logCases: { startingValue: TestState; updateValue: TestState; phrase: string }[] = [ + { + startingValue: null, + updateValue: null, + phrase: "null to null", + }, + { + startingValue: null, + updateValue: new TestState(), + phrase: "null to non-null", + }, + { + startingValue: new TestState(), + updateValue: null, + phrase: "non-null to null", + }, + { + startingValue: new TestState(), + updateValue: new TestState(), + phrase: "non-null to non-null", + }, + ]; + + it.each(logCases)( + "should log meta info about the update", + async ({ startingValue, updateValue, phrase }) => { + diskStorageService.internalUpdateStore({ + [`user_${userId}_fake_fake`]: startingValue, + }); + const state = new DefaultSingleUserState( + userId, + new UserKeyDefinition(testStateDefinition, "fake", { + deserializer: TestState.fromJSON, + clearOn: [], + debug: { + enableUpdateLogging: true, + }, + }), + diskStorageService, + stateEventRegistrarService, + logService, + ); + + await state.update(() => updateValue); + + expect(logService.info).toHaveBeenCalledWith( + `Updating 'user_${userId}_fake_fake' from ${phrase}`, + ); + }, + ); }); describe("update races", () => { diff --git a/libs/common/src/platform/state/implementations/default-single-user-state.ts b/libs/common/src/platform/state/implementations/default-single-user-state.ts index fc25e0afbc5..4cfba1ffa95 100644 --- a/libs/common/src/platform/state/implementations/default-single-user-state.ts +++ b/libs/common/src/platform/state/implementations/default-single-user-state.ts @@ -1,6 +1,7 @@ import { Observable, combineLatest, of } from "rxjs"; import { UserId } from "../../../types/guid"; +import { LogService } from "../../abstractions/log.service"; import { AbstractStorageService, ObservableStorageService, @@ -22,8 +23,9 @@ export class DefaultSingleUserState keyDefinition: UserKeyDefinition, chosenLocation: AbstractStorageService & ObservableStorageService, private stateEventRegistrarService: StateEventRegistrarService, + logService: LogService, ) { - super(keyDefinition.buildKey(userId), chosenLocation, keyDefinition); + super(keyDefinition.buildKey(userId), chosenLocation, keyDefinition, logService); this.combinedState$ = combineLatest([of(userId), this.state$]); } diff --git a/libs/common/src/platform/state/implementations/specific-state.provider.spec.ts b/libs/common/src/platform/state/implementations/specific-state.provider.spec.ts index 94e9c9c3e26..1b5a36445c9 100644 --- a/libs/common/src/platform/state/implementations/specific-state.provider.spec.ts +++ b/libs/common/src/platform/state/implementations/specific-state.provider.spec.ts @@ -3,6 +3,7 @@ import { mock } from "jest-mock-extended"; import { mockAccountServiceWith } from "../../../../spec/fake-account-service"; import { FakeStorageService } from "../../../../spec/fake-storage.service"; import { UserId } from "../../../types/guid"; +import { LogService } from "../../abstractions/log.service"; import { StorageServiceProvider } from "../../services/storage-service.provider"; import { KeyDefinition } from "../key-definition"; import { StateDefinition } from "../state-definition"; @@ -19,6 +20,7 @@ import { DefaultSingleUserStateProvider } from "./default-single-user-state.prov describe("Specific State Providers", () => { const storageServiceProvider = mock(); const stateEventRegistrarService = mock(); + const logService = mock(); let singleSut: DefaultSingleUserStateProvider; let activeSut: DefaultActiveUserStateProvider; @@ -34,9 +36,10 @@ describe("Specific State Providers", () => { singleSut = new DefaultSingleUserStateProvider( storageServiceProvider, stateEventRegistrarService, + logService, ); activeSut = new DefaultActiveUserStateProvider(mockAccountServiceWith(null), singleSut); - globalSut = new DefaultGlobalStateProvider(storageServiceProvider); + globalSut = new DefaultGlobalStateProvider(storageServiceProvider, logService); }); const fakeDiskStateDefinition = new StateDefinition("fake", "disk"); diff --git a/libs/common/src/platform/state/implementations/state-base.ts b/libs/common/src/platform/state/implementations/state-base.ts index 9beab1200a1..defd372eba6 100644 --- a/libs/common/src/platform/state/implementations/state-base.ts +++ b/libs/common/src/platform/state/implementations/state-base.ts @@ -7,16 +7,19 @@ import { merge, share, switchMap, + tap, timeout, timer, } from "rxjs"; import { Jsonify } from "type-fest"; import { StorageKey } from "../../../types/state"; +import { LogService } from "../../abstractions/log.service"; import { AbstractStorageService, ObservableStorageService, } from "../../abstractions/storage.service"; +import { DebugOptions } from "../key-definition"; import { StateUpdateOptions, populateOptionsWithDefault } from "../state-update-options"; import { getStoredValue } from "./util"; @@ -25,6 +28,7 @@ import { getStoredValue } from "./util"; type KeyDefinitionRequirements = { deserializer: (jsonState: Jsonify) => T; cleanupDelayMs: number; + debug: Required; }; export abstract class StateBase> { @@ -36,6 +40,7 @@ export abstract class StateBase> protected readonly key: StorageKey, protected readonly storageService: AbstractStorageService & ObservableStorageService, protected readonly keyDefinition: KeyDef, + protected readonly logService: LogService, ) { const storageUpdate$ = storageService.updates$.pipe( filter((storageUpdate) => storageUpdate.key === key), @@ -53,6 +58,18 @@ export abstract class StateBase> storageUpdate$, ); + if (keyDefinition.debug.enableRetrievalLogging) { + state$ = state$.pipe( + tap({ + next: (v) => { + this.logService.info( + `Retrieving '${key}' from storage, value is ${v == null ? "null" : "non-null"}`, + ); + }, + }), + ); + } + // If 0 cleanup is chosen, treat this as absolutely no cache if (keyDefinition.cleanupDelayMs !== 0) { state$ = state$.pipe( @@ -104,6 +121,11 @@ export abstract class StateBase> } protected async doStorageSave(newState: T, oldState: T) { + if (this.keyDefinition.debug.enableUpdateLogging) { + this.logService.info( + `Updating '${this.key}' from ${oldState == null ? "null" : "non-null"} to ${newState == null ? "null" : "non-null"}`, + ); + } await this.storageService.save(this.key, newState); } diff --git a/libs/common/src/platform/state/key-definition.spec.ts b/libs/common/src/platform/state/key-definition.spec.ts index f68fb6f5ab6..4eed0384811 100644 --- a/libs/common/src/platform/state/key-definition.spec.ts +++ b/libs/common/src/platform/state/key-definition.spec.ts @@ -1,6 +1,6 @@ import { Opaque } from "type-fest"; -import { KeyDefinition } from "./key-definition"; +import { DebugOptions, KeyDefinition } from "./key-definition"; import { StateDefinition } from "./state-definition"; const fakeStateDefinition = new StateDefinition("fake", "disk"); @@ -16,6 +16,97 @@ describe("KeyDefinition", () => { }); }); }); + + it("normalizes debug options set to undefined", () => { + const keyDefinition = new KeyDefinition(fakeStateDefinition, "fake", { + deserializer: (v) => v, + debug: undefined, + }); + + expect(keyDefinition.debug.enableUpdateLogging).toBe(false); + }); + + it("normalizes no debug options", () => { + const keyDefinition = new KeyDefinition(fakeStateDefinition, "fake", { + deserializer: (v) => v, + }); + + expect(keyDefinition.debug.enableUpdateLogging).toBe(false); + }); + + const cases: { + debug: DebugOptions | undefined; + expectedEnableUpdateLogging: boolean; + expectedEnableRetrievalLogging: boolean; + }[] = [ + { + debug: undefined, + expectedEnableUpdateLogging: false, + expectedEnableRetrievalLogging: false, + }, + { + debug: {}, + expectedEnableUpdateLogging: false, + expectedEnableRetrievalLogging: false, + }, + { + debug: { + enableUpdateLogging: false, + }, + expectedEnableUpdateLogging: false, + expectedEnableRetrievalLogging: false, + }, + { + debug: { + enableRetrievalLogging: false, + }, + expectedEnableUpdateLogging: false, + expectedEnableRetrievalLogging: false, + }, + { + debug: { + enableUpdateLogging: true, + }, + expectedEnableUpdateLogging: true, + expectedEnableRetrievalLogging: false, + }, + { + debug: { + enableRetrievalLogging: true, + }, + expectedEnableUpdateLogging: false, + expectedEnableRetrievalLogging: true, + }, + { + debug: { + enableRetrievalLogging: false, + enableUpdateLogging: false, + }, + expectedEnableUpdateLogging: false, + expectedEnableRetrievalLogging: false, + }, + { + debug: { + enableRetrievalLogging: true, + enableUpdateLogging: true, + }, + expectedEnableUpdateLogging: true, + expectedEnableRetrievalLogging: true, + }, + ]; + + it.each(cases)( + "normalizes debug options to correct values when given $debug", + ({ debug, expectedEnableUpdateLogging, expectedEnableRetrievalLogging }) => { + const keyDefinition = new KeyDefinition(fakeStateDefinition, "fake", { + deserializer: (v) => v, + debug: debug, + }); + + expect(keyDefinition.debug.enableUpdateLogging).toBe(expectedEnableUpdateLogging); + expect(keyDefinition.debug.enableRetrievalLogging).toBe(expectedEnableRetrievalLogging); + }, + ); }); describe("cleanupDelayMs", () => { diff --git a/libs/common/src/platform/state/key-definition.ts b/libs/common/src/platform/state/key-definition.ts index a69cec8cafc..f5781fe2c16 100644 --- a/libs/common/src/platform/state/key-definition.ts +++ b/libs/common/src/platform/state/key-definition.ts @@ -5,6 +5,28 @@ import { StorageKey } from "../../types/state"; import { array, record } from "./deserialization-helpers"; import { StateDefinition } from "./state-definition"; +export type DebugOptions = { + /** + * When true, logs will be written that look like the following: + * + * ``` + * "Updating 'global_myState_myKey' from null to non-null" + * "Updating 'user_32265eda-62ff-4797-9ead-22214772f888_myState_myKey' from non-null to null." + * ``` + * + * It does not include the value of the data, only whether it is null or non-null. + */ + enableUpdateLogging?: boolean; + + /** + * When true, logs will be written that look like the following everytime a value is retrieved from storage. + * + * "Retrieving 'global_myState_myKey' from storage, value is null." + * "Retrieving 'user_32265eda-62ff-4797-9ead-22214772f888_myState_myKey' from storage, value is non-null." + */ + enableRetrievalLogging?: boolean; +}; + /** * A set of options for customizing the behavior of a {@link KeyDefinition} */ @@ -24,6 +46,11 @@ export type KeyDefinitionOptions = { * Defaults to 1000ms. */ readonly cleanupDelayMs?: number; + + /** + * Options for configuring the debugging behavior, see individual options for more info. + */ + readonly debug?: DebugOptions; }; /** @@ -32,6 +59,8 @@ export type KeyDefinitionOptions = { * sub-divides that domain into specific keys. */ export class KeyDefinition { + readonly debug: Required; + /** * Creates a new instance of a KeyDefinition * @param stateDefinition The state definition for which this key belongs to. @@ -55,6 +84,13 @@ export class KeyDefinition { `'cleanupDelayMs' must be greater than or equal to 0. Value of ${options.cleanupDelayMs} passed to key ${this.errorKeyName} `, ); } + + // Normalize optional debug options + const { enableUpdateLogging = false, enableRetrievalLogging = false } = options.debug ?? {}; + this.debug = { + enableUpdateLogging, + enableRetrievalLogging, + }; } /** diff --git a/libs/common/src/platform/state/user-key-definition.ts b/libs/common/src/platform/state/user-key-definition.ts index a70675c7888..1548ab2a7c1 100644 --- a/libs/common/src/platform/state/user-key-definition.ts +++ b/libs/common/src/platform/state/user-key-definition.ts @@ -3,7 +3,7 @@ import { StorageKey } from "../../types/state"; import { Utils } from "../misc/utils"; import { array, record } from "./deserialization-helpers"; -import { KeyDefinitionOptions } from "./key-definition"; +import { DebugOptions, KeyDefinitionOptions } from "./key-definition"; import { StateDefinition } from "./state-definition"; export type ClearEvent = "lock" | "logout"; @@ -21,6 +21,11 @@ export class UserKeyDefinition { */ readonly clearOn: ClearEvent[]; + /** + * Normalized options used for debugging purposes. + */ + readonly debug: Required; + constructor( readonly stateDefinition: StateDefinition, readonly key: string, @@ -38,6 +43,13 @@ export class UserKeyDefinition { // Filter out repeat values this.clearOn = Array.from(new Set(options.clearOn)); + + // Normalize optional debug options + const { enableUpdateLogging = false, enableRetrievalLogging = false } = options.debug ?? {}; + this.debug = { + enableUpdateLogging, + enableRetrievalLogging, + }; } /** From f1c177b3cf644ebb4b45cae7b7950090a1601299 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:24:22 -0400 Subject: [PATCH 19/46] [PM-9980] Turn off cache for certain keys (#10226) * Turn Off Cache For DeviceKey * Turn Off Cache For AppId --- .../src/auth/services/device-trust.service.implementation.ts | 1 + libs/common/src/platform/services/app-id.service.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/libs/common/src/auth/services/device-trust.service.implementation.ts b/libs/common/src/auth/services/device-trust.service.implementation.ts index cc80ea888c3..d02969c5d5f 100644 --- a/libs/common/src/auth/services/device-trust.service.implementation.ts +++ b/libs/common/src/auth/services/device-trust.service.implementation.ts @@ -37,6 +37,7 @@ export const DEVICE_KEY = new UserKeyDefinition( deserializer: (deviceKey) => deviceKey ? (SymmetricCryptoKey.fromJSON(deviceKey) as DeviceKey) : null, clearOn: [], // Device key is needed to log back into device, so we can't clear it automatically during lock or logout + cleanupDelayMs: 0, }, ); diff --git a/libs/common/src/platform/services/app-id.service.ts b/libs/common/src/platform/services/app-id.service.ts index 56e9516bce7..883a81a52db 100644 --- a/libs/common/src/platform/services/app-id.service.ts +++ b/libs/common/src/platform/services/app-id.service.ts @@ -6,6 +6,7 @@ import { APPLICATION_ID_DISK, GlobalStateProvider, KeyDefinition } from "../stat export const APP_ID_KEY = new KeyDefinition(APPLICATION_ID_DISK, "appId", { deserializer: (value: string) => value, + cleanupDelayMs: 0, }); export const ANONYMOUS_APP_ID_KEY = new KeyDefinition(APPLICATION_ID_DISK, "anonymousAppId", { deserializer: (value: string) => value, From 271d65c9537d68fbb0f8a00c9d07b30d562b8f85 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:19:21 -0400 Subject: [PATCH 20/46] Turn On Debug Info For 2 Keys (#10316) --- .../src/auth/services/device-trust.service.implementation.ts | 4 ++++ libs/common/src/platform/services/app-id.service.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/libs/common/src/auth/services/device-trust.service.implementation.ts b/libs/common/src/auth/services/device-trust.service.implementation.ts index d02969c5d5f..fe0f2cff0ab 100644 --- a/libs/common/src/auth/services/device-trust.service.implementation.ts +++ b/libs/common/src/auth/services/device-trust.service.implementation.ts @@ -38,6 +38,10 @@ export const DEVICE_KEY = new UserKeyDefinition( deviceKey ? (SymmetricCryptoKey.fromJSON(deviceKey) as DeviceKey) : null, clearOn: [], // Device key is needed to log back into device, so we can't clear it automatically during lock or logout cleanupDelayMs: 0, + debug: { + enableRetrievalLogging: true, + enableUpdateLogging: true, + }, }, ); diff --git a/libs/common/src/platform/services/app-id.service.ts b/libs/common/src/platform/services/app-id.service.ts index 883a81a52db..3578d96c409 100644 --- a/libs/common/src/platform/services/app-id.service.ts +++ b/libs/common/src/platform/services/app-id.service.ts @@ -7,6 +7,10 @@ import { APPLICATION_ID_DISK, GlobalStateProvider, KeyDefinition } from "../stat export const APP_ID_KEY = new KeyDefinition(APPLICATION_ID_DISK, "appId", { deserializer: (value: string) => value, cleanupDelayMs: 0, + debug: { + enableRetrievalLogging: true, + enableUpdateLogging: true, + }, }); export const ANONYMOUS_APP_ID_KEY = new KeyDefinition(APPLICATION_ID_DISK, "anonymousAppId", { deserializer: (value: string) => value, From 00f6920a86ee05ab3d0edb630762779c6015c2ad Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Mon, 29 Jul 2024 08:10:12 -0700 Subject: [PATCH 21/46] [PM-8379] Implement loading state in vault v2 (#10302) --- .../src/vault/popup/components/vault/vault-v2.component.html | 2 +- .../src/vault/popup/components/vault/vault-v2.component.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/browser/src/vault/popup/components/vault/vault-v2.component.html b/apps/browser/src/vault/popup/components/vault/vault-v2.component.html index c36d480e9c6..3279d28e931 100644 --- a/apps/browser/src/vault/popup/components/vault/vault-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault/vault-v2.component.html @@ -1,4 +1,4 @@ - + diff --git a/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts index 777e44f0e16..0e256476619 100644 --- a/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts @@ -54,6 +54,7 @@ export class VaultV2Component implements OnInit, OnDestroy { cipherType = CipherType; protected favoriteCiphers$ = this.vaultPopupItemsService.favoriteCiphers$; protected remainingCiphers$ = this.vaultPopupItemsService.remainingCiphers$; + protected loading$ = this.vaultPopupItemsService.loading$; protected newItemItemValues$: Observable = this.vaultPopupListFiltersService.filters$.pipe( From ad01a529e8827a52a612be5444628075b05fb8b3 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Mon, 29 Jul 2024 08:13:56 -0700 Subject: [PATCH 22/46] [PM-9959] [PM-9962] Browser Refresh - Passkey Fixes (#10299) * [PM-9959] Expose Fido2SessionData interface * [PM-9959] Ensure cipherType is passed during passkey creation * [PM-9959] Add beforeSubmit hook to cipherForm * [PM-9959] Add support for Fido2 credential creation in add-edit-v2 * [PM-9959] Ensure cipherType defaults to CipherType.Login if none is available * [PM-9959] Add support for name and username to be passed in as query params for initial form values * [PM-9962] Hide remove passkey button when cipher has "except passwords" permissions --- .../popup/components/fido2/fido2.component.ts | 3 +- .../add-edit/add-edit-v2.component.html | 3 +- .../add-edit/add-edit-v2.component.ts | 102 ++++++++++++++++-- .../components/vault/add-edit.component.ts | 1 + .../popup/utils/fido2-popout-session-data.ts | 31 ++++-- .../cipher-form-config.service.ts | 2 + .../components/cipher-form.component.ts | 20 +++- .../components/identity/identity.component.ts | 4 + .../item-details-section.component.ts | 2 +- .../login-details-section.component.html | 2 +- .../login-details-section.component.spec.ts | 12 ++- .../login-details-section.component.ts | 7 +- .../default-cipher-form-config.service.ts | 2 +- 13 files changed, 166 insertions(+), 25 deletions(-) diff --git a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts index 3a8c69cba95..c0389f5afdd 100644 --- a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts +++ b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts @@ -18,7 +18,7 @@ import { DomainSettingsService } from "@bitwarden/common/autofill/services/domai import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { SecureNoteType, CipherType } from "@bitwarden/common/vault/enums"; +import { CipherType, SecureNoteType } from "@bitwarden/common/vault/enums"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { CardView } from "@bitwarden/common/vault/models/view/card.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -311,6 +311,7 @@ export class Fido2Component implements OnInit, OnDestroy { queryParams: { name: data.credentialName || data.rpId, uri: this.url, + type: CipherType.Login.toString(), uilocation: "popout", username: data.userName, senderTabId: this.senderTabId, diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html index 0ae2f0af01f..863b5e8dc39 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html @@ -10,7 +10,8 @@ *ngIf="!loading" formId="cipherForm" [config]="config" - (cipherSaved)="onCipherSaved()" + (cipherSaved)="onCipherSaved($event)" + [beforeSubmit]="checkFido2UserVerification" [submitBtn]="submitBtn" > >; @@ -99,7 +120,7 @@ export type AddEditQueryParams = Partial>; AsyncActionsModule, ], }) -export class AddEditV2Component { +export class AddEditV2Component implements OnInit { headerText: string; config: CipherFormConfig; @@ -111,16 +132,50 @@ export class AddEditV2Component { return this.config?.originalCipher?.id as CipherId; } + private fido2PopoutSessionData$ = fido2PopoutSessionData$(); + private fido2PopoutSessionData: Fido2SessionData; + + private get inFido2PopoutWindow() { + return BrowserPopupUtils.inPopout(window) && this.fido2PopoutSessionData.isFido2Session; + } + + private get inSingleActionPopout() { + return BrowserPopupUtils.inSingleActionPopout(window, VaultPopoutType.addEditVaultItem); + } + constructor( private route: ActivatedRoute, private location: Location, private i18nService: I18nService, private addEditFormConfigService: CipherFormConfigService, private router: Router, + private popupCloseWarningService: PopupCloseWarningService, ) { this.subscribeToParams(); } + async ngOnInit() { + this.fido2PopoutSessionData = await firstValueFrom(this.fido2PopoutSessionData$); + + if (BrowserPopupUtils.inPopout(window)) { + this.popupCloseWarningService.enable(); + } + } + + /** + * Called before the form is submitted, allowing us to handle Fido2 user verification. + */ + protected checkFido2UserVerification: () => Promise = async () => { + if (!this.inFido2PopoutWindow) { + // Not in a Fido2 popout window, no need to handle user verification. + return true; + } + + // TODO use fido2 user verification service once user verification for passkeys is approved for production. + // We are bypassing user verification pending approval for production. + return true; + }; + /** * Navigates to previous view or view-cipher path * depending on the history length. @@ -129,6 +184,17 @@ export class AddEditV2Component { * forced into a popout window. */ async handleBackButton() { + if (this.inFido2PopoutWindow) { + this.popupCloseWarningService.disable(); + BrowserFido2UserInterfaceSession.abortPopout(this.fido2PopoutSessionData.sessionId); + return; + } + + if (this.inSingleActionPopout) { + await BrowserPopupUtils.closeSingleActionPopout(VaultPopoutType.addEditVaultItem); + return; + } + if (history.length === 1) { await this.router.navigate(["/view-cipher"], { queryParams: { cipherId: this.originalCipherId }, @@ -138,7 +204,25 @@ export class AddEditV2Component { } } - onCipherSaved() { + async onCipherSaved(cipher: CipherView) { + if (BrowserPopupUtils.inPopout(window)) { + this.popupCloseWarningService.disable(); + } + + if (this.inFido2PopoutWindow) { + BrowserFido2UserInterfaceSession.confirmNewCredentialResponse( + this.fido2PopoutSessionData.sessionId, + cipher.id, + this.fido2PopoutSessionData.userVerification, + ); + return; + } + + if (this.inSingleActionPopout) { + await BrowserPopupUtils.closeSingleActionPopout(VaultPopoutType.addEditVaultItem, 1000); + return; + } + this.location.back(); } @@ -189,6 +273,12 @@ export class AddEditV2Component { if (params.uri) { config.initialValues.loginUri = params.uri; } + if (params.username) { + config.initialValues.username = params.username; + } + if (params.name) { + config.initialValues.name = params.name; + } } setHeader(mode: CipherFormMode, type: CipherType) { diff --git a/apps/browser/src/vault/popup/components/vault/add-edit.component.ts b/apps/browser/src/vault/popup/components/vault/add-edit.component.ts index ee1e46abab2..fb3fa75ebac 100644 --- a/apps/browser/src/vault/popup/components/vault/add-edit.component.ts +++ b/apps/browser/src/vault/popup/components/vault/add-edit.component.ts @@ -397,6 +397,7 @@ export class AddEditComponent extends BaseAddEditComponent { } // TODO: Remove and use fido2 user verification service once user verification for passkeys is approved for production. + // Be sure to make the same changes to add-edit-v2.component.ts if applicable private async handleFido2UserVerification( sessionId: string, userVerification: boolean, diff --git a/apps/browser/src/vault/popup/utils/fido2-popout-session-data.ts b/apps/browser/src/vault/popup/utils/fido2-popout-session-data.ts index a4d95ff48f6..79a15294f67 100644 --- a/apps/browser/src/vault/popup/utils/fido2-popout-session-data.ts +++ b/apps/browser/src/vault/popup/utils/fido2-popout-session-data.ts @@ -2,6 +2,18 @@ import { inject } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { map } from "rxjs"; +/** + * Interface describing the data that can be passed as query params for a FIDO2 session. + */ +export interface Fido2SessionData { + isFido2Session: boolean; + sessionId: string; + fallbackSupported: boolean; + userVerification: boolean; + senderUrl: string; + fromLock: boolean; +} + /** * Function to retrieve FIDO2 session data from query parameters. * Expected to be used within components tied to routes with these query parameters. @@ -10,13 +22,16 @@ export function fido2PopoutSessionData$() { const route = inject(ActivatedRoute); return route.queryParams.pipe( - map((queryParams) => ({ - isFido2Session: queryParams.sessionId != null, - sessionId: queryParams.sessionId as string, - fallbackSupported: queryParams.fallbackSupported === "true", - userVerification: queryParams.userVerification === "true", - senderUrl: queryParams.senderUrl as string, - fromLock: queryParams.fromLock === "true", - })), + map( + (queryParams) => + { + isFido2Session: queryParams.sessionId != null, + sessionId: queryParams.sessionId as string, + fallbackSupported: queryParams.fallbackSupported === "true", + userVerification: queryParams.userVerification === "true", + senderUrl: queryParams.senderUrl as string, + fromLock: queryParams.fromLock === "true", + }, + ), ); } diff --git a/libs/vault/src/cipher-form/abstractions/cipher-form-config.service.ts b/libs/vault/src/cipher-form/abstractions/cipher-form-config.service.ts index 334fbae5903..837c9d11ede 100644 --- a/libs/vault/src/cipher-form/abstractions/cipher-form-config.service.ts +++ b/libs/vault/src/cipher-form/abstractions/cipher-form-config.service.ts @@ -22,6 +22,8 @@ export type OptionalInitialValues = { organizationId?: OrganizationId; collectionIds?: CollectionId[]; loginUri?: string; + username?: string; + name?: string; }; /** diff --git a/libs/vault/src/cipher-form/components/cipher-form.component.ts b/libs/vault/src/cipher-form/components/cipher-form.component.ts index b666e6833bd..d7f96d19c59 100644 --- a/libs/vault/src/cipher-form/components/cipher-form.component.ts +++ b/libs/vault/src/cipher-form/components/cipher-form.component.ts @@ -90,6 +90,12 @@ export class CipherFormComponent implements AfterViewInit, OnInit, OnChanges, Ci @Input() submitBtn?: ButtonComponent; + /** + * Optional function to call before submitting the form. If the function returns false, the form will not be submitted. + */ + @Input() + beforeSubmit: () => Promise; + /** * Event emitted when the cipher is saved successfully. */ @@ -213,7 +219,17 @@ export class CipherFormComponent implements AfterViewInit, OnInit, OnChanges, Ci return; } - await this.addEditFormService.saveCipher(this.updatedCipherView, this.config); + if (this.beforeSubmit) { + const shouldSubmit = await this.beforeSubmit(); + if (!shouldSubmit) { + return; + } + } + + const savedCipher = await this.addEditFormService.saveCipher( + this.updatedCipherView, + this.config, + ); this.toastService.showToast({ variant: "success", @@ -225,6 +241,6 @@ export class CipherFormComponent implements AfterViewInit, OnInit, OnChanges, Ci ), }); - this.cipherSaved.emit(this.updatedCipherView); + this.cipherSaved.emit(savedCipher); }; } diff --git a/libs/vault/src/cipher-form/components/identity/identity.component.ts b/libs/vault/src/cipher-form/components/identity/identity.component.ts index 9e84f8ea6c7..ae712b915b3 100644 --- a/libs/vault/src/cipher-form/components/identity/identity.component.ts +++ b/libs/vault/src/cipher-form/components/identity/identity.component.ts @@ -113,6 +113,10 @@ export class IdentitySectionComponent implements OnInit { if (this.originalCipherView && this.originalCipherView.id) { this.populateFormData(); + } else { + this.identityForm.patchValue({ + username: this.cipherFormContainer.config.initialValues?.username || "", + }); } } diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts index 75cb160c927..99ecd84cd29 100644 --- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts +++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts @@ -165,7 +165,7 @@ export class ItemDetailsSectionComponent implements OnInit { await this.initFromExistingCipher(); } else { this.itemDetailsForm.setValue({ - name: "", + name: this.initialValues?.name || "", organizationId: this.initialValues?.organizationId || this.defaultOwner, folderId: this.initialValues?.folderId || null, collectionIds: [], diff --git a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.html b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.html index 085354d3db0..09327a145fb 100644 --- a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.html +++ b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.html @@ -67,7 +67,7 @@ bitIconButton="bwi-minus-circle" buttonType="danger" bitSuffix - *ngIf="loginDetailsForm.enabled" + *ngIf="loginDetailsForm.enabled && viewHiddenFields" [bitAction]="removePasskey" data-testid="remove-passkey-button" [appA11yTitle]="'removePasskey' | i18n" diff --git a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts index 0fe4b128d3f..31a0bb8ab5c 100644 --- a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts +++ b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts @@ -452,6 +452,8 @@ describe("LoginDetailsSectionComponent", () => { fixture = TestBed.createComponent(LoginDetailsSectionComponent); component = fixture.componentInstance; + + jest.spyOn(component, "viewHiddenFields", "get").mockReturnValue(true); }); it("renders the passkey field when available", () => { @@ -469,7 +471,7 @@ describe("LoginDetailsSectionComponent", () => { it("renders the passkey remove button when editable", () => { fixture.detectChanges(); - expect(getRemovePasskeyBtn).not.toBeNull(); + expect(getRemovePasskeyBtn()).not.toBeNull(); }); it("does not render the passkey remove button when not editable", () => { @@ -480,6 +482,14 @@ describe("LoginDetailsSectionComponent", () => { expect(getRemovePasskeyBtn()).toBeNull(); }); + it("does not render the passkey remove button when viewHiddenFields is false", () => { + jest.spyOn(component, "viewHiddenFields", "get").mockReturnValue(false); + + fixture.detectChanges(); + + expect(getRemovePasskeyBtn()).toBeNull(); + }); + it("hides the passkey field when missing a passkey", () => { (cipherFormContainer.originalCipherView as CipherView).login.fido2Credentials = []; diff --git a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts index 61a51fadaa8..57d2243820f 100644 --- a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts +++ b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts @@ -144,9 +144,10 @@ export class LoginDetailsSectionComponent implements OnInit { } private async initNewCipher() { - this.loginDetailsForm.controls.password.patchValue( - await this.generationService.generateInitialPassword(), - ); + this.loginDetailsForm.patchValue({ + username: this.cipherFormContainer.config.initialValues?.username || "", + password: await this.generationService.generateInitialPassword(), + }); } captureTotp = async () => { diff --git a/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts b/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts index 166e1bd58d9..4171f153ecc 100644 --- a/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts +++ b/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts @@ -48,7 +48,7 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService { return { mode, - cipherType, + cipherType: cipher?.type ?? cipherType ?? CipherType.Login, admin: false, allowPersonalOwnership, originalCipher: cipher, From 22bb1316cd1726673fdd6e34b5a3d92ec8809572 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Mon, 29 Jul 2024 11:16:00 -0400 Subject: [PATCH 23/46] PM-10047 update name input in item details (#10294) --- .../item-details-v2.component.html | 18 ++++++++++-------- .../item-details/item-details-v2.component.ts | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/libs/vault/src/cipher-view/item-details/item-details-v2.component.html b/libs/vault/src/cipher-view/item-details/item-details-v2.component.html index 77042755f88..ee8b17e71cc 100644 --- a/libs/vault/src/cipher-view/item-details/item-details-v2.component.html +++ b/libs/vault/src/cipher-view/item-details/item-details-v2.component.html @@ -7,14 +7,16 @@ - + + +
- + {{ "securityCode" | i18n }} - + {{ "licenseNumber" | i18n }} @@ -99,7 +99,7 @@ - + {{ "phone" | i18n }} @@ -148,7 +148,7 @@ - + {{ "country" | i18n }} diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html index 05286eaaa3d..0d79d4c2506 100644 --- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html +++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html @@ -18,7 +18,11 @@
- + {{ "owner" | i18n }} - + {{ "folder" | i18n }}
- + {{ "collections" | i18n }} - + {{ "authenticatorKey" | i18n }}
+ + + + + + + + + + + diff --git a/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.ts b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.ts new file mode 100644 index 00000000000..a1d688c25e7 --- /dev/null +++ b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.ts @@ -0,0 +1,318 @@ +import { StepperSelectionEvent } from "@angular/cdk/stepper"; +import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core"; +import { FormBuilder, Validators } from "@angular/forms"; +import { ActivatedRoute, Router } from "@angular/router"; +import { Subject, takeUntil } from "rxjs"; + +import { PasswordInputResult, RegistrationFinishService } from "@bitwarden/auth/angular"; +import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "@bitwarden/auth/common"; +import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; +import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; +import { OrganizationBillingServiceAbstraction as OrganizationBillingService } from "@bitwarden/common/billing/abstractions/organization-billing.service"; +import { ProductTierType, ProductType } from "@bitwarden/common/billing/enums"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; +import { ToastService } from "@bitwarden/components"; + +import { + OrganizationCreatedEvent, + SubscriptionProduct, + TrialOrganizationType, +} from "../../../billing/accounts/trial-initiation/trial-billing-step.component"; +import { RouterService } from "../../../core/router.service"; +import { AcceptOrganizationInviteService } from "../../organization-invite/accept-organization.service"; +import { VerticalStepperComponent } from "../vertical-stepper/vertical-stepper.component"; + +@Component({ + selector: "app-complete-trial-initiation", + templateUrl: "complete-trial-initiation.component.html", +}) +export class CompleteTrialInitiationComponent implements OnInit, OnDestroy { + @ViewChild("stepper", { static: false }) verticalStepper: VerticalStepperComponent; + + /** Password Manager or Secrets Manager */ + product: ProductType; + /** The tier of product being subscribed to */ + productTier: ProductTierType; + /** Product types that display steppers for Password Manager */ + stepperProductTypes: ProductTierType[] = [ + ProductTierType.Teams, + ProductTierType.Enterprise, + ProductTierType.Families, + ]; + + /** Display multi-step trial flow when true */ + useTrialStepper = false; + + /** True, registering a password is in progress */ + submitting = false; + + /** Valid product types, used to filter out invalid query parameters */ + validProducts = [ProductType.PasswordManager, ProductType.SecretsManager]; + + orgInfoSubLabel = ""; + orgId = ""; + orgLabel = ""; + billingSubLabel = ""; + enforcedPolicyOptions: MasterPasswordPolicyOptions; + + /** User's email address associated with the trial */ + email = ""; + /** Token from the backend associated with the email verification */ + emailVerificationToken: string; + + orgInfoFormGroup = this.formBuilder.group({ + name: ["", { validators: [Validators.required, Validators.maxLength(50)], updateOn: "change" }], + billingEmail: [""], + }); + + private destroy$ = new Subject(); + protected readonly SubscriptionProduct = SubscriptionProduct; + protected readonly ProductType = ProductType; + + constructor( + protected router: Router, + private route: ActivatedRoute, + private formBuilder: FormBuilder, + private logService: LogService, + private policyApiService: PolicyApiServiceAbstraction, + private policyService: PolicyService, + private i18nService: I18nService, + private routerService: RouterService, + private organizationBillingService: OrganizationBillingService, + private acceptOrganizationInviteService: AcceptOrganizationInviteService, + private toastService: ToastService, + private registrationFinishService: RegistrationFinishService, + private validationService: ValidationService, + private loginStrategyService: LoginStrategyServiceAbstraction, + ) {} + + async ngOnInit(): Promise { + this.route.queryParams.pipe(takeUntil(this.destroy$)).subscribe((qParams) => { + // Retrieve email from query params + if (qParams.email != null && qParams.email.indexOf("@") > -1) { + this.email = qParams.email; + this.orgInfoFormGroup.controls.billingEmail.setValue(qParams.email); + } + + // Show email validation toast when coming from email + if (qParams.fromEmail && qParams.fromEmail === "true") { + this.toastService.showToast({ + title: null, + message: this.i18nService.t("emailVerifiedV2"), + variant: "success", + }); + } + + if (qParams.token != null) { + this.emailVerificationToken = qParams.token; + } + + const product = parseInt(qParams.product); + + // Get product from query params, default to password manager + this.product = this.validProducts.includes(product) ? product : ProductType.PasswordManager; + + const productTierParam = parseInt(qParams.productTier) as ProductTierType; + + /** Only show the trial stepper for a subset of types */ + const showPasswordManagerStepper = this.stepperProductTypes.includes(productTierParam); + + /** All types of secret manager should see the trial stepper */ + const showSecretsManagerStepper = this.product === ProductType.SecretsManager; + + if ((showPasswordManagerStepper || showSecretsManagerStepper) && !isNaN(productTierParam)) { + this.productTier = productTierParam; + + this.orgLabel = this.planTypeDisplay; + + this.useTrialStepper = true; + } + + // Are they coming from an email for sponsoring a families organization + // After logging in redirect them to setup the families sponsorship + this.setupFamilySponsorship(qParams.sponsorshipToken); + }); + + const invite = await this.acceptOrganizationInviteService.getOrganizationInvite(); + let policies: Policy[] | null = null; + + if (invite != null) { + try { + policies = await this.policyApiService.getPoliciesByToken( + invite.organizationId, + invite.token, + invite.email, + invite.organizationUserId, + ); + } catch (e) { + this.logService.error(e); + } + } + + if (policies !== null) { + this.policyService + .masterPasswordPolicyOptions$(policies) + .pipe(takeUntil(this.destroy$)) + .subscribe((enforcedPasswordPolicyOptions) => { + this.enforcedPolicyOptions = enforcedPasswordPolicyOptions; + }); + } + + this.orgInfoFormGroup.controls.name.valueChanges + .pipe(takeUntil(this.destroy$)) + .subscribe(() => { + this.orgInfoFormGroup.controls.name.markAsTouched(); + }); + } + + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } + + /** Handle manual stepper change */ + verticalStepChange(event: StepperSelectionEvent) { + if (event.selectedIndex === 1 && this.orgInfoFormGroup.controls.name.value === "") { + this.orgInfoSubLabel = this.planInfoLabel; + } else if (event.previouslySelectedIndex === 1) { + this.orgInfoSubLabel = this.orgInfoFormGroup.controls.name.value; + } + } + + /** Update local details from organization created event */ + createdOrganization(event: OrganizationCreatedEvent) { + this.orgId = event.organizationId; + this.billingSubLabel = event.planDescription; + this.verticalStepper.next(); + } + + /** Move the user to the previous step */ + previousStep() { + this.verticalStepper.previous(); + } + + get isSecretsManagerFree() { + return this.product === ProductType.SecretsManager && this.productTier === ProductTierType.Free; + } + + get planTypeDisplay() { + switch (this.productTier) { + case ProductTierType.Teams: + return "Teams"; + case ProductTierType.Enterprise: + return "Enterprise"; + case ProductTierType.Families: + return "Families"; + default: + return ""; + } + } + + get planInfoLabel() { + switch (this.productTier) { + case ProductTierType.Teams: + return this.i18nService.t("enterTeamsOrgInfo"); + case ProductTierType.Enterprise: + return this.i18nService.t("enterEnterpriseOrgInfo"); + case ProductTierType.Families: + return this.i18nService.t("enterFamiliesOrgInfo"); + default: + return ""; + } + } + + get trialOrganizationType(): TrialOrganizationType { + if (this.productTier === ProductTierType.Free) { + return null; + } + + return this.productTier; + } + + /** Create an organization unless the trial is for secrets manager */ + async conditionallyCreateOrganization(): Promise { + if (!this.isSecretsManagerFree) { + this.verticalStepper.next(); + return; + } + + const response = await this.organizationBillingService.startFree({ + organization: { + name: this.orgInfoFormGroup.value.name, + billingEmail: this.orgInfoFormGroup.value.billingEmail, + }, + plan: { + type: 0, + subscribeToSecretsManager: true, + isFromSecretsManagerTrial: true, + }, + }); + + this.orgId = response.id; + this.verticalStepper.next(); + } + + /** + * Complete the users registration with their password. + * + * When a the trial stepper isn't used, redirect the user to the login page. + */ + async handlePasswordSubmit(passwordInputResult: PasswordInputResult) { + if (!this.useTrialStepper) { + await this.finishRegistration(passwordInputResult); + this.submitting = false; + + await this.router.navigate(["/login"], { queryParams: { email: this.email } }); + return; + } + + const captchaToken = await this.finishRegistration(passwordInputResult); + + if (captchaToken == null) { + this.submitting = false; + return; + } + + await this.logIn(passwordInputResult.password, captchaToken); + + this.submitting = false; + + this.verticalStepper.next(); + } + + private setupFamilySponsorship(sponsorshipToken: string) { + if (sponsorshipToken != null) { + const route = this.router.createUrlTree(["setup/families-for-enterprise"], { + queryParams: { plan: sponsorshipToken }, + }); + this.routerService.setPreviousUrl(route.toString()); + } + } + + /** Logs the user in based using the token received by the `finishRegistration` method */ + private async logIn(masterPassword: string, captchaBypassToken: string): Promise { + const credentials = new PasswordLoginCredentials( + this.email, + masterPassword, + captchaBypassToken, + null, + ); + + await this.loginStrategyService.logIn(credentials); + } + + finishRegistration(passwordInputResult: PasswordInputResult) { + this.submitting = true; + return this.registrationFinishService + .finishRegistration(this.email, passwordInputResult, this.emailVerificationToken) + .catch((e) => { + this.validationService.showError(e); + this.submitting = false; + return null; + }); + } +} diff --git a/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/resolver/free-trial-text.resolver.spec.ts b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/resolver/free-trial-text.resolver.spec.ts new file mode 100644 index 00000000000..f9831c6dc47 --- /dev/null +++ b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/resolver/free-trial-text.resolver.spec.ts @@ -0,0 +1,58 @@ +import { ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router"; + +import { ProductTierType, ProductType } from "@bitwarden/common/billing/enums"; + +import { freeTrialTextResolver } from "./free-trial-text.resolver"; + +const route = { + queryParams: {}, +} as ActivatedRouteSnapshot; + +const routerStateSnapshot = {} as RouterStateSnapshot; + +describe("freeTrialTextResolver", () => { + [ + { + param: ProductType.PasswordManager, + keyBase: "startYour7DayFreeTrialOfBitwardenPasswordManager", + }, + { + param: ProductType.SecretsManager, + keyBase: "startYour7DayFreeTrialOfBitwardenSecretsManager", + }, + { + param: `${ProductType.PasswordManager},${ProductType.SecretsManager}`, + keyBase: "startYour7DayFreeTrialOfBitwarden", + }, + ].forEach(({ param, keyBase }) => { + describe(`when product is ${param}`, () => { + beforeEach(() => { + route.queryParams.product = `${param}`; + }); + + it("returns teams trial text", () => { + route.queryParams.productTier = ProductTierType.Teams; + + expect(freeTrialTextResolver(route, routerStateSnapshot)).toBe(`${keyBase}ForTeams`); + }); + + it("returns enterprise trial text", () => { + route.queryParams.productTier = ProductTierType.Enterprise; + + expect(freeTrialTextResolver(route, routerStateSnapshot)).toBe(`${keyBase}ForEnterprise`); + }); + + it("returns families trial text", () => { + route.queryParams.productTier = ProductTierType.Families; + + expect(freeTrialTextResolver(route, routerStateSnapshot)).toBe(`${keyBase}ForFamilies`); + }); + + it("returns default trial text", () => { + route.queryParams.productTier = ""; + + expect(freeTrialTextResolver(route, routerStateSnapshot)).toBe(keyBase); + }); + }); + }); +}); diff --git a/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/resolver/free-trial-text.resolver.ts b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/resolver/free-trial-text.resolver.ts new file mode 100644 index 00000000000..7dec807fd45 --- /dev/null +++ b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/resolver/free-trial-text.resolver.ts @@ -0,0 +1,43 @@ +import { ActivatedRouteSnapshot, ResolveFn } from "@angular/router"; + +import { ProductType, ProductTierType } from "@bitwarden/common/billing/enums"; + +export const freeTrialTextResolver: ResolveFn = ( + route: ActivatedRouteSnapshot, +): string | null => { + const { product, productTier } = route.queryParams; + const products: ProductType[] = (product ?? "").split(",").map((p: string) => parseInt(p)); + + const onlyPasswordManager = products.length === 1 && products[0] === ProductType.PasswordManager; + const onlySecretsManager = products.length === 1 && products[0] === ProductType.SecretsManager; + const forTeams = parseInt(productTier) === ProductTierType.Teams; + const forEnterprise = parseInt(productTier) === ProductTierType.Enterprise; + const forFamilies = parseInt(productTier) === ProductTierType.Families; + + switch (true) { + case onlyPasswordManager && forTeams: + return "startYour7DayFreeTrialOfBitwardenPasswordManagerForTeams"; + case onlyPasswordManager && forEnterprise: + return "startYour7DayFreeTrialOfBitwardenPasswordManagerForEnterprise"; + case onlyPasswordManager && forFamilies: + return "startYour7DayFreeTrialOfBitwardenPasswordManagerForFamilies"; + case onlyPasswordManager: + return "startYour7DayFreeTrialOfBitwardenPasswordManager"; + case onlySecretsManager && forTeams: + return "startYour7DayFreeTrialOfBitwardenSecretsManagerForTeams"; + case onlySecretsManager && forEnterprise: + return "startYour7DayFreeTrialOfBitwardenSecretsManagerForEnterprise"; + case onlySecretsManager && forFamilies: + return "startYour7DayFreeTrialOfBitwardenSecretsManagerForFamilies"; + case onlySecretsManager: + return "startYour7DayFreeTrialOfBitwardenSecretsManager"; + case forTeams: + return "startYour7DayFreeTrialOfBitwardenForTeams"; + case forEnterprise: + return "startYour7DayFreeTrialOfBitwardenForEnterprise"; + case forFamilies: + return "startYour7DayFreeTrialOfBitwardenForFamilies"; + default: + return "startYour7DayFreeTrialOfBitwarden"; + } +}; diff --git a/apps/web/src/app/auth/trial-initiation/confirmation-details.component.html b/apps/web/src/app/auth/trial-initiation/confirmation-details.component.html index 69bd57cd3a3..e706239f9ff 100644 --- a/apps/web/src/app/auth/trial-initiation/confirmation-details.component.html +++ b/apps/web/src/app/auth/trial-initiation/confirmation-details.component.html @@ -1,5 +1,10 @@
-

{{ "trialThankYou" | i18n: orgLabel }}

+

+ {{ "trialThankYou" | i18n: orgLabel }} +

+

+ {{ "smFreeTrialThankYou" | i18n }} +

  • diff --git a/apps/web/src/app/auth/trial-initiation/confirmation-details.component.ts b/apps/web/src/app/auth/trial-initiation/confirmation-details.component.ts index 95976fe7273..69d08e627a5 100644 --- a/apps/web/src/app/auth/trial-initiation/confirmation-details.component.ts +++ b/apps/web/src/app/auth/trial-initiation/confirmation-details.component.ts @@ -1,5 +1,7 @@ import { Component, Input } from "@angular/core"; +import { ProductType } from "@bitwarden/common/billing/enums"; + @Component({ selector: "app-trial-confirmation-details", templateUrl: "confirmation-details.component.html", @@ -7,4 +9,7 @@ import { Component, Input } from "@angular/core"; export class ConfirmationDetailsComponent { @Input() email: string; @Input() orgLabel: string; + @Input() product?: ProductType = ProductType.PasswordManager; + + protected readonly Product = ProductType; } diff --git a/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts b/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts index 57d982fd00b..9a7ed7e429d 100644 --- a/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts +++ b/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts @@ -2,6 +2,7 @@ import { CdkStepperModule } from "@angular/cdk/stepper"; import { TitleCasePipe } from "@angular/common"; import { NgModule } from "@angular/core"; +import { InputPasswordComponent } from "@bitwarden/auth/angular"; import { FormFieldModule } from "@bitwarden/components"; import { OrganizationCreateModule } from "../../admin-console/organizations/create/organization-create.module"; @@ -14,6 +15,7 @@ import { TrialBillingStepComponent } from "../../billing/accounts/trial-initiati import { EnvironmentSelectorModule } from "../../components/environment-selector/environment-selector.module"; import { SharedModule } from "../../shared"; +import { CompleteTrialInitiationComponent } from "./complete-trial-initiation/complete-trial-initiation.component"; import { ConfirmationDetailsComponent } from "./confirmation-details.component"; import { AbmEnterpriseContentComponent } from "./content/abm-enterprise-content.component"; import { AbmTeamsContentComponent } from "./content/abm-teams-content.component"; @@ -51,9 +53,11 @@ import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.modul PaymentComponent, TaxInfoComponent, TrialBillingStepComponent, + InputPasswordComponent, ], declarations: [ TrialInitiationComponent, + CompleteTrialInitiationComponent, EnterpriseContentComponent, TeamsContentComponent, ConfirmationDetailsComponent, @@ -82,7 +86,7 @@ import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.modul SecretsManagerTrialFreeStepperComponent, SecretsManagerTrialPaidStepperComponent, ], - exports: [TrialInitiationComponent], + exports: [TrialInitiationComponent, CompleteTrialInitiationComponent], providers: [TitleCasePipe], }) export class TrialInitiationModule {} diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 65414317cbc..32dcb695a8f 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -47,6 +47,8 @@ import { EmergencyAccessComponent } from "./auth/settings/emergency-access/emerg import { EmergencyAccessViewComponent } from "./auth/settings/emergency-access/view/emergency-access-view.component"; import { SecurityRoutingModule } from "./auth/settings/security/security-routing.module"; import { SsoComponent } from "./auth/sso.component"; +import { CompleteTrialInitiationComponent } from "./auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component"; +import { freeTrialTextResolver } from "./auth/trial-initiation/complete-trial-initiation/resolver/free-trial-text.resolver"; import { TrialInitiationComponent } from "./auth/trial-initiation/trial-initiation.component"; import { TwoFactorAuthComponent } from "./auth/two-factor-auth.component"; import { TwoFactorComponent } from "./auth/two-factor.component"; @@ -400,6 +402,28 @@ const routes: Routes = [ titleId: "removeMasterPassword", } satisfies DataProperties & AnonLayoutWrapperData, }, + { + path: "trial-initiation", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + component: CompleteTrialInitiationComponent, + resolve: { + pageTitle: freeTrialTextResolver, + }, + data: { + maxWidth: "3xl", + } satisfies AnonLayoutWrapperData, + }, + { + path: "secrets-manager-trial-initiation", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + component: CompleteTrialInitiationComponent, + resolve: { + pageTitle: freeTrialTextResolver, + }, + data: { + maxWidth: "3xl", + } satisfies AnonLayoutWrapperData, + }, ], }, { diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 2aed43787e5..2be00bb8896 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8414,6 +8414,51 @@ "manageBillingFromProviderPortalMessage": { "message": "Manage billing from the Provider Portal" }, + "startYour7DayFreeTrialOfBitwarden": { + "message": "Start your 7-Day free trial of Bitwarden" + }, + "startYour7DayFreeTrialOfBitwardenForTeams": { + "message": "Start your 7-Day free trial of Bitwarden for Teams" + }, + "startYour7DayFreeTrialOfBitwardenForFamilies": { + "message": "Start your 7-Day free trial of Bitwarden for Families" + }, + "startYour7DayFreeTrialOfBitwardenForEnterprise": { + "message": "Start your 7-Day free trial of Bitwarden for Enterprise" + }, + "startYour7DayFreeTrialOfBitwardenSecretsManager": { + "message": "Start your 7-Day free trial of Bitwarden Secrets Manager" + }, + "startYour7DayFreeTrialOfBitwardenSecretsManagerForTeams": { + "message": "Start your 7-Day free trial of Bitwarden Secrets Manager for Teams" + }, + "startYour7DayFreeTrialOfBitwardenSecretsManagerForFamilies": { + "message": "Start your 7-Day free trial of Bitwarden Secrets Manager for Families" + }, + "startYour7DayFreeTrialOfBitwardenSecretsManagerForEnterprise": { + "message": "Start your 7-Day free trial of Bitwarden Secrets Manager for Enterprise" + }, + "startYour7DayFreeTrialOfBitwardenPasswordManager": { + "message": "Start your 7-Day free trial of Bitwarden Password Manager" + }, + "startYour7DayFreeTrialOfBitwardenPasswordManagerForTeams": { + "message": "Start your 7-Day free trial of Bitwarden Password Manager for Teams" + }, + "startYour7DayFreeTrialOfBitwardenPasswordManagerForFamilies": { + "message": "Start your 7-Day free trial of Bitwarden Password Manager for Families" + }, + "startYour7DayFreeTrialOfBitwardenPasswordManagerForEnterprise": { + "message": "Start your 7-Day free trial of Bitwarden Password Manager for Enterprise" + }, + "enterTeamsOrgInfo": { + "message": "Enter your Teams organization information" + }, + "enterFamiliesOrgInfo": { + "message": "Enter your Families organization information" + }, + "enterEnterpriseOrgInfo": { + "message": "Enter your Enterprise organization information" + }, "viewItemsIn": { "message": "View items in $NAME$", "description": "Button to view the contents of a folder or collection", diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.html b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.html index 6d5fc9b8dad..cfd436d93ae 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.html +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.html @@ -3,6 +3,7 @@ [subtitle]="pageSubtitle" [icon]="pageIcon" [showReadonlyHostname]="showReadonlyHostname" + [maxWidth]="maxWidth" > diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts index 0bedf221e06..7559e35cdc3 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts @@ -13,6 +13,7 @@ export interface AnonLayoutWrapperData { pageSubtitle?: string; pageIcon?: Icon; showReadonlyHostname?: boolean; + maxWidth?: "md" | "3xl"; } @Component({ @@ -27,6 +28,7 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy { protected pageSubtitle: string; protected pageIcon: Icon; protected showReadonlyHostname: boolean; + protected maxWidth: "md" | "3xl"; constructor( private router: Router, @@ -75,6 +77,7 @@ export class AnonLayoutWrapperComponent implements OnInit, OnDestroy { } this.showReadonlyHostname = Boolean(firstChildRouteData["showReadonlyHostname"]); + this.maxWidth = firstChildRouteData["maxWidth"]; } private listenForServiceDataChanges() { diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.html b/libs/auth/src/angular/anon-layout/anon-layout.component.html index 8fed6a82266..d6e80c27709 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.html +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.html @@ -15,6 +15,7 @@

{ localMasterKeyHash: "localMasterKeyHash", kdfConfig: DEFAULT_KDF_CONFIG, hint: "hint", + password: "password", }; userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey; diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts index e4837641ef3..26b6b0e529f 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts @@ -110,6 +110,7 @@ describe("DefaultSetPasswordJitService", () => { localMasterKeyHash: "localMasterKeyHash", hint: "hint", kdfConfig: DEFAULT_KDF_CONFIG, + password: "password", }; credentials = { diff --git a/libs/common/src/billing/enums/index.ts b/libs/common/src/billing/enums/index.ts index e11cd9d8294..3d89c7a5462 100644 --- a/libs/common/src/billing/enums/index.ts +++ b/libs/common/src/billing/enums/index.ts @@ -4,3 +4,4 @@ export * from "./plan-type.enum"; export * from "./transaction-type.enum"; export * from "./bitwarden-product-type.enum"; export * from "./product-tier-type.enum"; +export * from "./product-type.enum"; From 8c78959aaf51e96765b05fa9e2e0408bd6ae24b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Tue, 30 Jul 2024 08:40:52 -0400 Subject: [PATCH 33/46] [PM-9613] port forwarders to integrations (#10075) * introduced forwarder integrations * simply contexts * report error and message when both are present in an RPC response --- .../integration/integration-configuration.ts | 7 +- .../integration/integration-context.spec.ts | 69 +++-- .../tools/integration/integration-context.ts | 27 +- .../tools/integration/rpc/rest-client.spec.ts | 150 +++++++++- .../src/tools/integration/rpc/rest-client.ts | 113 ++++--- libs/common/src/tools/state/classifier.ts | 37 +++ .../src/tools/state/secret-classifier.ts | 6 +- .../tools/state/secret-key-definition.spec.ts | 12 +- .../src/tools/state/secret-key-definition.ts | 10 +- libs/tools/generator/core/src/data/index.ts | 1 + .../generator/core/src/data/integrations.ts | 15 + .../src/engine/forwarder-configuration.ts | 51 ++++ .../core/src/engine/forwarder-context.spec.ts | 84 ++++++ .../core/src/engine/forwarder-context.ts | 63 ++++ libs/tools/generator/core/src/engine/index.ts | 3 + .../rpc/create-forwarding-address.spec.ts | 117 ++++++++ .../engine/rpc/create-forwarding-address.ts | 64 ++++ .../src/engine/rpc/get-account-id.spec.ts | 83 ++++++ .../core/src/engine/rpc/get-account-id.ts | 41 +++ .../generator/core/src/engine/rpc/index.ts | 2 + .../generator/core/src/engine/settings.ts | 20 ++ libs/tools/generator/core/src/index.ts | 1 + .../core/src/integration/addy-io.spec.ts | 83 ++++++ .../generator/core/src/integration/addy-io.ts | 73 +++++ .../core/src/integration/duck-duck-go.spec.ts | 78 +++++ .../core/src/integration/duck-duck-go.ts | 61 ++++ .../core/src/integration/fastmail.spec.ts | 215 ++++++++++++++ .../core/src/integration/fastmail.ts | 127 ++++++++ .../src/integration/firefox-relay.spec.ts | 85 ++++++ .../core/src/integration/firefox-relay.ts | 69 +++++ .../src/integration/forward-email.spec.ts | 96 ++++++ .../core/src/integration/forward-email.ts | 76 +++++ .../generator/core/src/integration/index.ts | 6 + .../core/src/integration/simple-login.spec.ts | 92 ++++++ .../core/src/integration/simple-login.ts | 74 +++++ .../strategies/catchall-generator-strategy.ts | 4 +- .../eff-username-generator-strategy.ts | 4 +- .../forwarder-generator-strategy.spec.ts | 103 +++++-- .../forwarder-generator-strategy.ts | 127 ++++++-- .../src/strategies/forwarders/addy-io.spec.ts | 233 --------------- .../core/src/strategies/forwarders/addy-io.ts | 100 ------- .../forwarders/duck-duck-go.spec.ts | 144 --------- .../src/strategies/forwarders/duck-duck-go.ts | 75 ----- .../strategies/forwarders/fastmail.spec.ts | 281 ------------------ .../src/strategies/forwarders/fastmail.ts | 150 ---------- .../forwarders/firefox-relay.spec.ts | 147 --------- .../strategies/forwarders/firefox-relay.ts | 82 ----- .../forwarders/forward-email.spec.ts | 277 ----------------- .../strategies/forwarders/forward-email.ts | 104 ------- .../src/strategies/forwarders/mocks.jest.ts | 22 -- .../forwarders/simple-login.spec.ts | 209 ------------- .../src/strategies/forwarders/simple-login.ts | 88 ------ .../generator/core/src/strategies/index.ts | 7 +- .../src/strategies/options-classifier.spec.ts | 60 ++++ .../core/src/strategies/options-classifier.ts | 44 +++ .../passphrase-generator-strategy.ts | 4 +- .../strategies/password-generator-strategy.ts | 4 +- .../core/src/strategies/storage.spec.ts | 120 -------- .../generator/core/src/strategies/storage.ts | 125 -------- .../subaddress-generator-strategy.ts | 4 +- .../src/types/catchall-generator-options.ts | 5 +- .../types/eff-username-generator-options.ts | 4 +- .../core/src/types/forwarder-options.ts | 62 +--- .../src/types/subaddress-generator-options.ts | 5 +- libs/tools/generator/core/src/util.ts | 9 +- ...eate-legacy-username-generation-service.ts | 57 +++- ...legacy-password-generation.service.spec.ts | 5 +- ...legacy-username-generation.service.spec.ts | 13 +- .../src/legacy-username-generation.service.ts | 14 +- .../legacy/src/username-generation-options.ts | 4 +- 70 files changed, 2392 insertions(+), 2415 deletions(-) create mode 100644 libs/common/src/tools/state/classifier.ts create mode 100644 libs/tools/generator/core/src/data/integrations.ts create mode 100644 libs/tools/generator/core/src/engine/forwarder-configuration.ts create mode 100644 libs/tools/generator/core/src/engine/forwarder-context.spec.ts create mode 100644 libs/tools/generator/core/src/engine/forwarder-context.ts create mode 100644 libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts create mode 100644 libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts create mode 100644 libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts create mode 100644 libs/tools/generator/core/src/engine/rpc/get-account-id.ts create mode 100644 libs/tools/generator/core/src/engine/rpc/index.ts create mode 100644 libs/tools/generator/core/src/engine/settings.ts create mode 100644 libs/tools/generator/core/src/integration/addy-io.spec.ts create mode 100644 libs/tools/generator/core/src/integration/addy-io.ts create mode 100644 libs/tools/generator/core/src/integration/duck-duck-go.spec.ts create mode 100644 libs/tools/generator/core/src/integration/duck-duck-go.ts create mode 100644 libs/tools/generator/core/src/integration/fastmail.spec.ts create mode 100644 libs/tools/generator/core/src/integration/fastmail.ts create mode 100644 libs/tools/generator/core/src/integration/firefox-relay.spec.ts create mode 100644 libs/tools/generator/core/src/integration/firefox-relay.ts create mode 100644 libs/tools/generator/core/src/integration/forward-email.spec.ts create mode 100644 libs/tools/generator/core/src/integration/forward-email.ts create mode 100644 libs/tools/generator/core/src/integration/index.ts create mode 100644 libs/tools/generator/core/src/integration/simple-login.spec.ts create mode 100644 libs/tools/generator/core/src/integration/simple-login.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/addy-io.spec.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/addy-io.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.spec.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/fastmail.spec.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/fastmail.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/firefox-relay.spec.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/firefox-relay.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/forward-email.spec.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/forward-email.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/mocks.jest.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/simple-login.spec.ts delete mode 100644 libs/tools/generator/core/src/strategies/forwarders/simple-login.ts create mode 100644 libs/tools/generator/core/src/strategies/options-classifier.spec.ts create mode 100644 libs/tools/generator/core/src/strategies/options-classifier.ts diff --git a/libs/common/src/tools/integration/integration-configuration.ts b/libs/common/src/tools/integration/integration-configuration.ts index 8b8391b17ef..c435e6548f9 100644 --- a/libs/common/src/tools/integration/integration-configuration.ts +++ b/libs/common/src/tools/integration/integration-configuration.ts @@ -1,9 +1,12 @@ import { IntegrationContext } from "./integration-context"; import { IntegrationMetadata } from "./integration-metadata"; -import { ApiSettings, TokenHeader } from "./rpc"; +import { ApiSettings, IntegrationRequest, TokenHeader } from "./rpc"; /** Configures integration-wide settings */ export type IntegrationConfiguration = IntegrationMetadata & { /** Creates the authentication header for all integration remote procedure calls */ - authenticate: (settings: ApiSettings, context: IntegrationContext) => TokenHeader; + authenticate: ( + request: IntegrationRequest, + context: IntegrationContext, + ) => TokenHeader; }; diff --git a/libs/common/src/tools/integration/integration-context.spec.ts b/libs/common/src/tools/integration/integration-context.spec.ts index 85ec82eb404..58115c783c7 100644 --- a/libs/common/src/tools/integration/integration-context.spec.ts +++ b/libs/common/src/tools/integration/integration-context.spec.ts @@ -25,7 +25,7 @@ describe("IntegrationContext", () => { describe("baseUrl", () => { it("outputs the base url from metadata", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, null, i18n); const result = context.baseUrl(); @@ -41,15 +41,15 @@ describe("IntegrationContext", () => { }; i18n.t.mockReturnValue("error"); - const context = new IntegrationContext(noBaseUrl, i18n); + const context = new IntegrationContext(noBaseUrl, null, i18n); expect(() => context.baseUrl()).toThrow("error"); }); it("reads from the settings", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, { baseUrl: "httpbin.org" }, i18n); - const result = context.baseUrl({ baseUrl: "httpbin.org" }); + const result = context.baseUrl(); expect(result).toBe("httpbin.org"); }); @@ -62,9 +62,9 @@ describe("IntegrationContext", () => { baseUrl: "example.com", selfHost: "never", }; - const context = new IntegrationContext(selfHostNever, i18n); + const context = new IntegrationContext(selfHostNever, { baseUrl: "httpbin.org" }, i18n); - const result = context.baseUrl({ baseUrl: "httpbin.org" }); + const result = context.baseUrl(); expect(result).toBe("example.com"); }); @@ -77,11 +77,22 @@ describe("IntegrationContext", () => { baseUrl: "example.com", selfHost: "always", }; - const context = new IntegrationContext(selfHostAlways, i18n); + const context = new IntegrationContext(selfHostAlways, { baseUrl: "http.bin" }, i18n); // expect success - const result = context.baseUrl({ baseUrl: "http.bin" }); + const result = context.baseUrl(); expect(result).toBe("http.bin"); + }); + + it("fails when the settings are empty and selfhost is 'always'", () => { + const selfHostAlways: IntegrationMetadata = { + id: "simplelogin" as IntegrationId, // arbitrary + name: "Example", + extends: ["forwarder"], // arbitrary + baseUrl: "example.com", + selfHost: "always", + }; + const context = new IntegrationContext(selfHostAlways, {}, i18n); // expect error i18n.t.mockReturnValue("error"); @@ -97,7 +108,7 @@ describe("IntegrationContext", () => { selfHost: "maybe", }; - const context = new IntegrationContext(selfHostMaybe, i18n); + const context = new IntegrationContext(selfHostMaybe, null, i18n); const result = context.baseUrl(); @@ -113,9 +124,9 @@ describe("IntegrationContext", () => { selfHost: "maybe", }; - const context = new IntegrationContext(selfHostMaybe, i18n); + const context = new IntegrationContext(selfHostMaybe, { baseUrl: "httpbin.org" }, i18n); - const result = context.baseUrl({ baseUrl: "httpbin.org" }); + const result = context.baseUrl(); expect(result).toBe("httpbin.org"); }); @@ -123,39 +134,47 @@ describe("IntegrationContext", () => { describe("authenticationToken", () => { it("reads from the settings", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, { token: "example" }, i18n); - const result = context.authenticationToken({ token: "example" }); + const result = context.authenticationToken(); expect(result).toBe("example"); }); - it("base64 encodes the read value", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + it("suffix is appended to the token", () => { + const context = new IntegrationContext(EXAMPLE_META, { token: "example" }, i18n); - const result = context.authenticationToken({ token: "example" }, { base64: true }); + const result = context.authenticationToken({ suffix: " with suffix" }); + + expect(result).toBe("example with suffix"); + }); + + it("base64 encodes the read value", () => { + const context = new IntegrationContext(EXAMPLE_META, { token: "example" }, i18n); + + const result = context.authenticationToken({ base64: true }); expect(result).toBe("ZXhhbXBsZQ=="); }); it("throws an error when the value is missing", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, {}, i18n); i18n.t.mockReturnValue("error"); - expect(() => context.authenticationToken({})).toThrow("error"); + expect(() => context.authenticationToken()).toThrow("error"); }); - it("throws an error when the value is empty", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + it.each([[undefined], [null], [""]])("throws an error when the value is %p", (token) => { + const context = new IntegrationContext(EXAMPLE_META, { token }, i18n); i18n.t.mockReturnValue("error"); - expect(() => context.authenticationToken({ token: "" })).toThrow("error"); + expect(() => context.authenticationToken()).toThrow("error"); }); }); describe("website", () => { it("returns the website", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, null, i18n); const result = context.website({ website: "www.example.com" }); @@ -163,7 +182,7 @@ describe("IntegrationContext", () => { }); it("returns an empty string when the website is not specified", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, null, i18n); const result = context.website({ website: undefined }); @@ -173,7 +192,7 @@ describe("IntegrationContext", () => { describe("generatedBy", () => { it("creates generated by text", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, null, i18n); i18n.t.mockReturnValue("result"); const result = context.generatedBy({ website: null }); @@ -183,7 +202,7 @@ describe("IntegrationContext", () => { }); it("creates generated by text including the website", () => { - const context = new IntegrationContext(EXAMPLE_META, i18n); + const context = new IntegrationContext(EXAMPLE_META, null, i18n); i18n.t.mockReturnValue("result"); const result = context.generatedBy({ website: "www.example.com" }); diff --git a/libs/common/src/tools/integration/integration-context.ts b/libs/common/src/tools/integration/integration-context.ts index 5d676d40b7a..3debf54ba36 100644 --- a/libs/common/src/tools/integration/integration-context.ts +++ b/libs/common/src/tools/integration/integration-context.ts @@ -2,30 +2,33 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { Utils } from "@bitwarden/common/platform/misc/utils"; import { IntegrationMetadata } from "./integration-metadata"; -import { ApiSettings, SelfHostedApiSettings, IntegrationRequest } from "./rpc"; +import { ApiSettings, IntegrationRequest } from "./rpc"; /** Utilities for processing integration settings */ -export class IntegrationContext { +export class IntegrationContext { /** Instantiates an integration context * @param metadata - defines integration capabilities * @param i18n - localizes error messages */ constructor( readonly metadata: IntegrationMetadata, + protected settings: Settings, protected i18n: I18nService, ) {} /** Lookup the integration's baseUrl - * @param settings settings that override the baseUrl. * @returns the baseUrl for the API's integration point. * - By default this is defined by the metadata * - When a service allows self-hosting, this can be supplied by `settings`. * @throws a localized error message when a base URL is neither defined by the metadata or * supplied by an argument. */ - baseUrl(settings?: SelfHostedApiSettings) { + baseUrl(): string { // normalize baseUrl - const setting = settings && "baseUrl" in settings ? settings.baseUrl : ""; + const setting = + (this.settings && "baseUrl" in this.settings + ? (this.settings.baseUrl as string) + : undefined) ?? ""; let result = ""; // look up definition @@ -47,18 +50,24 @@ export class IntegrationContext { } /** look up a service API's authentication token - * @param settings store the API token * @param options.base64 when `true`, base64 encodes the result. Defaults to `false`. + * @param options.suffix a string to append to the token. Defaults to empty. * @returns the user's authentication token * @throws a localized error message when the token is invalid. + * @remarks the string is thrown for backwards compatibility */ - authenticationToken(settings: ApiSettings, options: { base64?: boolean } = null) { - if (!settings.token || settings.token === "") { + authenticationToken( + options: { base64?: boolean; suffix?: string } = null, + ): Settings extends ApiSettings ? string : never { + // normalize `token` then assert it has a value + let token = "token" in this.settings ? ((this.settings.token as string) ?? "") : ""; + if (token === "") { const error = this.i18n.t("forwaderInvalidToken", this.metadata.name); throw error; } - let token = settings.token; + // if a suffix exists, it needs to be included before encoding + token += options?.suffix ?? ""; if (options?.base64) { token = Utils.fromUtf8ToB64(token); } diff --git a/libs/common/src/tools/integration/rpc/rest-client.spec.ts b/libs/common/src/tools/integration/rpc/rest-client.spec.ts index b5a696648f1..e113ab9ff43 100644 --- a/libs/common/src/tools/integration/rpc/rest-client.spec.ts +++ b/libs/common/src/tools/integration/rpc/rest-client.spec.ts @@ -51,17 +51,41 @@ describe("RestClient", () => { expect(api.nativeFetch).toHaveBeenCalledWith(expectedRpc.fetchRequest); }); - it.each([[401], [403]])( + it.each([[401] /*,[403]*/])( "throws an invalid token error when HTTP status is %i", async (status) => { const client = new RestClient(api, i18n); const request: IntegrationRequest = { website: null }; - const response = mock({ status }); + const response = mock({ status, statusText: null }); api.nativeFetch.mockResolvedValue(response); const result = client.fetchJson(rpc, request); - await expect(result).rejects.toEqual("forwarderInvalidToken"); + await expect(result).rejects.toEqual("forwaderInvalidToken"); + }, + ); + + it.each([ + [401, null, null], + [401, undefined, undefined], + [401, undefined, null], + [403, null, null], + [403, undefined, undefined], + [403, undefined, null], + ])( + "throws an invalid token error when HTTP status is %i, message is %p, and error is %p", + async (status) => { + const client = new RestClient(api, i18n); + const request: IntegrationRequest = { website: null }; + const response = mock({ + status, + text: () => Promise.resolve(`{ "message": null, "error": null }`), + }); + api.nativeFetch.mockResolvedValue(response); + + const result = client.fetchJson(rpc, request); + + await expect(result).rejects.toEqual("forwaderInvalidToken"); }, ); @@ -83,16 +107,73 @@ describe("RestClient", () => { const result = client.fetchJson(rpc, request); - await expect(result).rejects.toEqual("forwarderInvalidTokenWithMessage"); + await expect(result).rejects.toEqual("forwaderInvalidTokenWithMessage"); expect(i18n.t).toHaveBeenCalledWith( - "forwarderInvalidTokenWithMessage", + "forwaderInvalidTokenWithMessage", "mock", "expected message", ); }, ); - it.each([[500], [501]])( + it.each([[401], [403]])( + "throws an invalid token detailed error when HTTP status is %i and the payload has a %s", + async (status) => { + const client = new RestClient(api, i18n); + const request: IntegrationRequest = { website: null }; + const response = mock({ + status, + text: () => + Promise.resolve(`{ "error": "that happened", "message": "expected message" }`), + }); + api.nativeFetch.mockResolvedValue(response); + + const result = client.fetchJson(rpc, request); + + await expect(result).rejects.toEqual("forwaderInvalidTokenWithMessage"); + expect(i18n.t).toHaveBeenCalledWith( + "forwaderInvalidTokenWithMessage", + "mock", + "that happened: expected message", + ); + }, + ); + + it.each([[429], [500], [501]])( + "throws a forwarder error when HTTP status is %i", + async (status) => { + const client = new RestClient(api, i18n); + const request: IntegrationRequest = { website: null }; + const response = mock({ status, statusText: null }); + api.nativeFetch.mockResolvedValue(response); + + const result = client.fetchJson(rpc, request); + + await expect(result).rejects.toEqual("forwarderUnknownError"); + expect(i18n.t).toHaveBeenCalledWith("forwarderUnknownError", "mock", undefined); + }, + ); + + it.each([[429], [500], [501]])( + "throws a forwarder error when HTTP status is %i and the body is empty", + async (status) => { + const client = new RestClient(api, i18n); + const request: IntegrationRequest = { website: null }; + const response = mock({ + status, + statusText: null, + text: () => Promise.resolve(""), + }); + api.nativeFetch.mockResolvedValue(response); + + const result = client.fetchJson(rpc, request); + + await expect(result).rejects.toEqual("forwarderUnknownError"); + expect(i18n.t).toHaveBeenCalledWith("forwarderUnknownError", "mock", undefined); + }, + ); + + it.each([[429], [500], [501]])( "throws a forwarder error with the status text when HTTP status is %i", async (status) => { const client = new RestClient(api, i18n); @@ -108,8 +189,10 @@ describe("RestClient", () => { ); it.each([ + [429, "message"], [500, "message"], [500, "message"], + [429, "error"], [501, "error"], [501, "error"], ])( @@ -130,6 +213,61 @@ describe("RestClient", () => { }, ); + it.each([[429], [500], [500]])( + "throws a detailed forwarder error when HTTP status is %i and the payload is a string", + async (status) => { + const client = new RestClient(api, i18n); + const request: IntegrationRequest = { website: null }; + const response = mock({ + status, + text: () => Promise.resolve('"expected message"'), + }); + api.nativeFetch.mockResolvedValue(response); + + const result = client.fetchJson(rpc, request); + + await expect(result).rejects.toEqual("forwarderError"); + expect(i18n.t).toHaveBeenCalledWith("forwarderError", "mock", "expected message"); + }, + ); + + it.each([[429], [500], [500]])( + "throws an unknown forwarder error when HTTP status is %i and the payload could contain an html tag", + async (status) => { + const client = new RestClient(api, i18n); + const request: IntegrationRequest = { website: null }; + const response = mock({ + status, + statusText: null, + text: () => Promise.resolve(""), + }); + api.nativeFetch.mockResolvedValue(response); + + const result = client.fetchJson(rpc, request); + + await expect(result).rejects.toEqual("forwarderUnknownError"); + expect(i18n.t).toHaveBeenCalledWith("forwarderUnknownError", "mock", undefined); + }, + ); + + it.each([[429], [500], [500]])( + "throws a unknown forwarder error when HTTP status is %i and the payload is malformed", + async (status) => { + const client = new RestClient(api, i18n); + const request: IntegrationRequest = { website: null }; + const response = mock({ + status, + text: () => Promise.resolve(`{ foo: "not json" }`), + }); + api.nativeFetch.mockResolvedValue(response); + + const result = client.fetchJson(rpc, request); + + await expect(result).rejects.toEqual("forwarderUnknownError"); + expect(i18n.t).toHaveBeenCalledWith("forwarderUnknownError", "mock", undefined); + }, + ); + it("outputs an error if there's no json payload", async () => { const client = new RestClient(api, i18n); rpc.hasJsonPayload.mockReturnValue(false); diff --git a/libs/common/src/tools/integration/rpc/rest-client.ts b/libs/common/src/tools/integration/rpc/rest-client.ts index 850e43ac7ee..05abb047d38 100644 --- a/libs/common/src/tools/integration/rpc/rest-client.ts +++ b/libs/common/src/tools/integration/rpc/rest-client.ts @@ -10,59 +10,96 @@ export class RestClient { private api: ApiService, private i18n: I18nService, ) {} + /** uses the fetch API to request a JSON payload. */ - async fetchJson( - rpc: JsonRpc, + // FIXME: once legacy password generator is removed, replace forwarder-specific error + // messages with RPC-generalized ones. + async fetchJson( + rpc: JsonRpc, params: Parameters, - ): Promise { + ): Promise { + // run the request const request = rpc.toRequest(params); const response = await this.api.nativeFetch(request); - // FIXME: once legacy password generator is removed, replace forwarder-specific error - // messages with RPC-generalized ones. - let error: string = undefined; - let cause: string = undefined; + let result: Result = undefined; + let errorKey: string = undefined; + let errorMessage: string = undefined; + const commonError = await this.detectCommonErrors(response); + if (commonError) { + [errorKey, errorMessage] = commonError; + } else if (rpc.hasJsonPayload(response)) { + [result, errorMessage] = rpc.processJson(await response.json()); + } + + if (result) { + return result; + } + + // handle failures + errorKey ??= errorMessage ? "forwarderError" : "forwarderUnknownError"; + const error = this.i18n.t(errorKey, rpc.requestor.name, errorMessage); + throw error; + } + + private async detectCommonErrors(response: Response): Promise<[string, string] | undefined> { if (response.status === 401 || response.status === 403) { - cause = await this.tryGetErrorMessage(response); - error = cause ? "forwarderInvalidTokenWithMessage" : "forwarderInvalidToken"; - } else if (response.status >= 500) { - cause = await this.tryGetErrorMessage(response); - cause = cause ?? response.statusText; - error = "forwarderError"; + const message = await this.tryGetErrorMessage(response); + const key = message ? "forwaderInvalidTokenWithMessage" : "forwaderInvalidToken"; + return [key, message]; + } else if (response.status === 429 || response.status >= 500) { + const message = await this.tryGetErrorMessage(response); + const key = message ? "forwarderError" : "forwarderUnknownError"; + return [key, message]; } - - let ok: Response = undefined; - if (!error && rpc.hasJsonPayload(response)) { - [ok, cause] = rpc.processJson(await response.json()); - } - - // success - if (ok) { - return ok; - } - - // failure - if (!error) { - error = cause ? "forwarderError" : "forwarderUnknownError"; - } - throw this.i18n.t(error, rpc.requestor.name, cause); } private async tryGetErrorMessage(response: Response) { const body = (await response.text()) ?? ""; - if (!body.startsWith("{")) { + // nullish continues processing; false returns undefined + const error = + this.tryFindErrorAsJson(body) ?? this.tryFindErrorAsText(body) ?? response.statusText; + + return error || undefined; + } + + private tryFindErrorAsJson(body: string) { + // tryParse JSON object or string + const parsable = body.startsWith("{") || body.startsWith(`'`) || body.startsWith(`"`); + if (!parsable) { + // fail-and-continue because it's not JSON + return undefined; + } + let parsed = undefined; + try { + parsed = JSON.parse(body); + } catch { + // fail-and-exit in case `body` is malformed JSON + return false; + } + + // could be a string + if (parsed && typeof parsed === "string") { + return parsed; + } + + // could be { error?: T, message?: U } + const error = parsed.error?.toString() ?? null; + const message = parsed.message?.toString() ?? null; + + // `false` signals no message found + const result = error && message ? `${error}: ${message}` : (error ?? message ?? false); + + return result; + } + + private tryFindErrorAsText(body: string) { + if (!body.length || body.includes("<")) { return undefined; } - const json = JSON.parse(body); - if ("error" in json) { - return json.error; - } else if ("message" in json) { - return json.message; - } - - return undefined; + return body; } } diff --git a/libs/common/src/tools/state/classifier.ts b/libs/common/src/tools/state/classifier.ts new file mode 100644 index 00000000000..aafbf293a6e --- /dev/null +++ b/libs/common/src/tools/state/classifier.ts @@ -0,0 +1,37 @@ +import { Jsonify } from "type-fest"; + +/** Classifies an object's JSON-serializable data by property into + * 3 categories: + * * Disclosed data MAY be stored in plaintext. + * * Excluded data MUST NOT be saved. + * * The remaining data is secret and MUST be stored using encryption. + * + * This type should not be used to classify functions. + * Data that cannot be serialized by JSON.stringify() should + * be excluded. + */ +export interface Classifier { + /** Partitions `secret` into its disclosed properties and secret properties. + * @param value The object to partition + * @returns an object that classifies secrets. + * The `disclosed` member is new and contains disclosed properties. + * The `secret` member is a copy of the secret parameter, including its + * prototype, with all disclosed and excluded properties deleted. + */ + classify(value: Plaintext): { disclosed: Jsonify; secret: Jsonify }; + + /** Merges the properties of `secret` and `disclosed`. When `secret` and + * `disclosed` contain the same property, the `secret` property overrides + * the `disclosed` property. + * @param disclosed an object whose disclosed properties are merged into + * the output. Unknown properties are ignored. + * @param secret an objects whose properties are merged into the output. + * Excluded properties are ignored. Unknown properties are retained. + * @returns a new object containing the merged data. + * + * @remarks Declassified data is always jsonified--the purpose of classifying it is + * to Jsonify it, + * which causes type conversions. + */ + declassify(disclosed: Jsonify, secret: Jsonify): Jsonify; +} diff --git a/libs/common/src/tools/state/secret-classifier.ts b/libs/common/src/tools/state/secret-classifier.ts index a26b01ac5dd..76e229f6e7e 100644 --- a/libs/common/src/tools/state/secret-classifier.ts +++ b/libs/common/src/tools/state/secret-classifier.ts @@ -1,5 +1,7 @@ import { Jsonify } from "type-fest"; +import { Classifier } from "./classifier"; + /** Classifies an object's JSON-serializable data by property into * 3 categories: * * Disclosed data MAY be stored in plaintext. @@ -10,7 +12,9 @@ import { Jsonify } from "type-fest"; * Data that cannot be serialized by JSON.stringify() should * be excluded. */ -export class SecretClassifier<Plaintext extends object, Disclosed, Secret> { +export class SecretClassifier<Plaintext extends object, Disclosed, Secret> + implements Classifier<Plaintext, Disclosed, Secret> +{ private constructor( disclosed: readonly (keyof Jsonify<Disclosed> & keyof Jsonify<Plaintext>)[], excluded: readonly (keyof Plaintext)[], diff --git a/libs/common/src/tools/state/secret-key-definition.spec.ts b/libs/common/src/tools/state/secret-key-definition.spec.ts index 33b2ec01d26..cab6b434477 100644 --- a/libs/common/src/tools/state/secret-key-definition.spec.ts +++ b/libs/common/src/tools/state/secret-key-definition.spec.ts @@ -1,15 +1,19 @@ +import { mock } from "jest-mock-extended"; +import { Jsonify } from "type-fest"; + import { GENERATOR_DISK, UserKeyDefinitionOptions } from "../../platform/state"; -import { SecretClassifier } from "./secret-classifier"; +import { Classifier } from "./classifier"; import { SecretKeyDefinition } from "./secret-key-definition"; describe("SecretKeyDefinition", () => { - const classifier = SecretClassifier.allSecret<{ foo: boolean }>(); + type TestData = { foo: boolean }; + const classifier = mock<Classifier<any, Record<string, never>, TestData>>(); const options: UserKeyDefinitionOptions<any> = { deserializer: (v: any) => v, clearOn: [] }; it("toEncryptedStateKey returns a key", () => { - const expectedOptions: UserKeyDefinitionOptions<any> = { - deserializer: (v: any) => v, + const expectedOptions: UserKeyDefinitionOptions<TestData> = { + deserializer: (v: Jsonify<TestData>) => v, cleanupDelayMs: 100, clearOn: ["logout", "lock"], }; diff --git a/libs/common/src/tools/state/secret-key-definition.ts b/libs/common/src/tools/state/secret-key-definition.ts index c33bb966850..c7ac433bdcd 100644 --- a/libs/common/src/tools/state/secret-key-definition.ts +++ b/libs/common/src/tools/state/secret-key-definition.ts @@ -2,7 +2,7 @@ import { UserKeyDefinitionOptions, UserKeyDefinition } from "../../platform/stat // eslint-disable-next-line -- `StateDefinition` used as an argument import { StateDefinition } from "../../platform/state/state-definition"; import { ClassifiedFormat } from "./classified-format"; -import { SecretClassifier } from "./secret-classifier"; +import { Classifier } from "./classifier"; /** Encryption and storage settings for data stored by a `SecretState`. */ @@ -10,7 +10,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec private constructor( readonly stateDefinition: StateDefinition, readonly key: string, - readonly classifier: SecretClassifier<Inner, Disclosed, Secret>, + readonly classifier: Classifier<Inner, Disclosed, Secret>, readonly options: UserKeyDefinitionOptions<Inner>, // type erasure is necessary here because typescript doesn't support // higher kinded types that generalize over collections. The invariants @@ -46,7 +46,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec static value<Value extends object, Disclosed, Secret>( stateDefinition: StateDefinition, key: string, - classifier: SecretClassifier<Value, Disclosed, Secret>, + classifier: Classifier<Value, Disclosed, Secret>, options: UserKeyDefinitionOptions<Value>, ) { return new SecretKeyDefinition<Value, void, Value, Disclosed, Secret>( @@ -70,7 +70,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec static array<Item extends object, Disclosed, Secret>( stateDefinition: StateDefinition, key: string, - classifier: SecretClassifier<Item, Disclosed, Secret>, + classifier: Classifier<Item, Disclosed, Secret>, options: UserKeyDefinitionOptions<Item>, ) { return new SecretKeyDefinition<Item[], number, Item, Disclosed, Secret>( @@ -94,7 +94,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec static record<Item extends object, Disclosed, Secret, Id extends string | number>( stateDefinition: StateDefinition, key: string, - classifier: SecretClassifier<Item, Disclosed, Secret>, + classifier: Classifier<Item, Disclosed, Secret>, options: UserKeyDefinitionOptions<Item>, ) { return new SecretKeyDefinition<Record<Id, Item>, Id, Item, Disclosed, Secret>( diff --git a/libs/tools/generator/core/src/data/index.ts b/libs/tools/generator/core/src/data/index.ts index 87c6584ae0f..d87e7f7c529 100644 --- a/libs/tools/generator/core/src/data/index.ts +++ b/libs/tools/generator/core/src/data/index.ts @@ -14,5 +14,6 @@ export * from "./default-simple-login-options"; export * from "./disabled-passphrase-generator-policy"; export * from "./disabled-password-generator-policy"; export * from "./forwarders"; +export * from "./integrations"; export * from "./policies"; export * from "./username-digits"; diff --git a/libs/tools/generator/core/src/data/integrations.ts b/libs/tools/generator/core/src/data/integrations.ts new file mode 100644 index 00000000000..6132891b368 --- /dev/null +++ b/libs/tools/generator/core/src/data/integrations.ts @@ -0,0 +1,15 @@ +import { AddyIo } from "../integration/addy-io"; +import { DuckDuckGo } from "../integration/duck-duck-go"; +import { Fastmail } from "../integration/fastmail"; +import { FirefoxRelay } from "../integration/firefox-relay"; +import { ForwardEmail } from "../integration/forward-email"; +import { SimpleLogin } from "../integration/simple-login"; + +export const Integrations = Object.freeze({ + AddyIo, + DuckDuckGo, + Fastmail, + FirefoxRelay, + ForwardEmail, + SimpleLogin, +} as const); diff --git a/libs/tools/generator/core/src/engine/forwarder-configuration.ts b/libs/tools/generator/core/src/engine/forwarder-configuration.ts new file mode 100644 index 00000000000..95c9add140a --- /dev/null +++ b/libs/tools/generator/core/src/engine/forwarder-configuration.ts @@ -0,0 +1,51 @@ +import { UserKeyDefinition } from "@bitwarden/common/platform/state"; +import { IntegrationConfiguration } from "@bitwarden/common/tools/integration/integration-configuration"; +import { ApiSettings } from "@bitwarden/common/tools/integration/rpc"; +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc/integration-request"; +import { RpcConfiguration } from "@bitwarden/common/tools/integration/rpc/rpc-definition"; +import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + +import { ForwarderContext } from "./forwarder-context"; + +/** Mixin for transmitting `getAccountId` result. */ +export type AccountRequest = { + accountId?: string; +}; + +/** definition of the create forwarding request api call for an integration */ +export type CreateForwardingEmailRpcDef< + Settings extends ApiSettings, + Request extends IntegrationRequest = IntegrationRequest, +> = RpcConfiguration<Request, ForwarderContext<Settings>, string>; + +/** definition of the get account id api call for an integration */ +export type GetAccountIdRpcDef< + Settings extends ApiSettings, + Request extends IntegrationRequest = IntegrationRequest, +> = RpcConfiguration<Request, ForwarderContext<Settings>, string>; + +/** Forwarder-specific static definition */ +export type ForwarderConfiguration< + Settings extends ApiSettings, + Request extends IntegrationRequest = IntegrationRequest, +> = IntegrationConfiguration & { + /** forwarder endpoint definition */ + forwarder: { + /** default value of all fields */ + defaultSettings: Partial<Settings>; + + /** forwarder settings storage */ + settings: UserKeyDefinition<Settings>; + + /** forwarder settings import buffer; `undefined` when there is no buffer. */ + importBuffer?: BufferedKeyDefinition<Settings>; + + /** createForwardingEmail RPC definition */ + createForwardingEmail: CreateForwardingEmailRpcDef<Settings, Request>; + + /** getAccountId RPC definition; the response updates `accountId` which has a + * structural mixin type `RequestAccount`. + */ + getAccountId?: GetAccountIdRpcDef<Settings, Request>; + }; +}; diff --git a/libs/tools/generator/core/src/engine/forwarder-context.spec.ts b/libs/tools/generator/core/src/engine/forwarder-context.spec.ts new file mode 100644 index 00000000000..9838dbcdbda --- /dev/null +++ b/libs/tools/generator/core/src/engine/forwarder-context.spec.ts @@ -0,0 +1,84 @@ +import { mock } from "jest-mock-extended"; + +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { ApiSettings } from "@bitwarden/common/tools/integration/rpc"; + +import { ForwarderConfiguration } from "./forwarder-configuration"; +import { ForwarderContext } from "./forwarder-context"; +import { EmailDomainSettings, EmailPrefixSettings } from "./settings"; + +describe("ForwarderContext", () => { + const i18n = mock<I18nService>({ + t(key: string) { + return key; + }, + }); + + describe("emailDomain", () => { + it("returns the domain", () => { + const settings = mock<EmailDomainSettings & ApiSettings>({ domain: "example.com" }); + const config = mock<ForwarderConfiguration<typeof settings>>(); + const context = new ForwarderContext(config, settings, i18n); + + const result = context.emailDomain(); + + expect(result).toEqual("example.com"); + }); + + it.each([[null], [undefined], [""]])("throws an error if the domain is %p", (domain) => { + const settings = mock<EmailDomainSettings & ApiSettings>({ domain }); + const config = mock<ForwarderConfiguration<typeof settings>>(); + const context = new ForwarderContext(config, settings, i18n); + + expect(() => context.emailDomain()).toThrow("forwarderNoDomain"); + }); + + it("throws an error if the domain is not an enumerable member of settings", () => { + const settings = {} as EmailDomainSettings & ApiSettings; + const config = mock<ForwarderConfiguration<typeof settings>>(); + const context = new ForwarderContext(config, settings, i18n); + + expect(() => context.emailDomain()).toThrow("forwarderNoDomain"); + }); + }); + + describe("emailPrefix", () => { + it("returns the prefix", () => { + const settings = mock<EmailPrefixSettings & ApiSettings>({ prefix: "foo" }); + const config = mock<ForwarderConfiguration<typeof settings>>(); + const context = new ForwarderContext(config, settings, i18n); + + const result = context.emailPrefix(); + + expect(result).toEqual("foo"); + }); + + it.each([[null], [undefined], [""]])("throws an error if the prefix is %p", (prefix) => { + const settings = mock<EmailPrefixSettings & ApiSettings>({ prefix }); + const config = mock<ForwarderConfiguration<typeof settings>>(); + const context = new ForwarderContext(config, settings, i18n); + + expect(() => context.emailPrefix()).toThrow("forwarderNoPrefix"); + }); + + it("throws an error if the prefix is not an enumerable member of settings", () => { + const settings = {} as EmailPrefixSettings & ApiSettings; + const config = mock<ForwarderConfiguration<typeof settings>>(); + const context = new ForwarderContext(config, settings, i18n); + + expect(() => context.emailPrefix()).toThrow("forwarderNoPrefix"); + }); + }); + + describe("missingAccountIdCause", () => { + it("returns the cause", () => { + const settings = mock<EmailDomainSettings & ApiSettings>(); + const config = mock<ForwarderConfiguration<typeof settings>>(); + const context = new ForwarderContext(config, settings, i18n); + + const result = context.missingAccountIdCause(); + + expect(result).toEqual("forwarderNoAccountId"); + }); + }); +}); diff --git a/libs/tools/generator/core/src/engine/forwarder-context.ts b/libs/tools/generator/core/src/engine/forwarder-context.ts new file mode 100644 index 00000000000..69fc37eafa4 --- /dev/null +++ b/libs/tools/generator/core/src/engine/forwarder-context.ts @@ -0,0 +1,63 @@ +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { IntegrationContext } from "@bitwarden/common/tools/integration/integration-context"; +import { ApiSettings } from "@bitwarden/common/tools/integration/rpc"; + +import { ForwarderConfiguration } from "./forwarder-configuration"; +import { EmailDomainSettings, EmailPrefixSettings } from "./settings"; + +/** + * Surfaces contextual information to forwarder integrations. + */ +export class ForwarderContext<Settings extends ApiSettings> extends IntegrationContext<Settings> { + /** Instantiates the context. + * @param configuration of the forwarder this context assists + * @param settings loaded from the forwarder's state + * @param i18n localizes error handling + */ + constructor( + readonly configuration: ForwarderConfiguration<Settings>, + settings: Settings, + i18n: I18nService, + ) { + super(configuration, settings, i18n); + } + + /** look up the domain part of an email address from the forwarder's settings. + * @returns a domain part of an email address + * @throws a localized error message when the domain isn't found. + * @remarks the string is thrown for backwards compatibility + */ + emailDomain(): Settings extends EmailDomainSettings ? string : never { + const domain = "domain" in this.settings ? (this.settings.domain ?? "") : ""; + if (domain === "") { + const error = this.i18n.t("forwarderNoDomain", this.configuration.name); + throw error; + } + + return domain as any; + } + + /** look up a prefix applied to the email address from the forwarder's settings. + * @returns the prefix + * @throws a localized error message when the prefix isn't found. + * @remarks the string is thrown for backwards compatibility + */ + emailPrefix(): Settings extends EmailPrefixSettings ? string : never { + const prefix = "prefix" in this.settings ? (this.settings.prefix ?? "") : ""; + if (prefix === "") { + const error = this.i18n.t("forwarderNoPrefix", this.configuration.name); + throw error; + } + + return prefix as any; + } + + /** look up a localized error message indicating an account id is required + * but wasn't found. + * @remarks this returns a string instead of throwing it so that the + * user can decide upon control flow. + */ + missingAccountIdCause() { + return this.i18n.t("forwarderNoAccountId", this.configuration.name); + } +} diff --git a/libs/tools/generator/core/src/engine/index.ts b/libs/tools/generator/core/src/engine/index.ts index 38e3195b966..c3d2aefef1b 100644 --- a/libs/tools/generator/core/src/engine/index.ts +++ b/libs/tools/generator/core/src/engine/index.ts @@ -1,4 +1,7 @@ export { CryptoServiceRandomizer } from "./crypto-service-randomizer"; +export { ForwarderConfiguration, AccountRequest } from "./forwarder-configuration"; +export { ForwarderContext } from "./forwarder-context"; +export * from "./settings"; export { EmailRandomizer } from "./email-randomizer"; export { EmailCalculator } from "./email-calculator"; export { PasswordRandomizer } from "./password-randomizer"; diff --git a/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts new file mode 100644 index 00000000000..d522b5f38ed --- /dev/null +++ b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts @@ -0,0 +1,117 @@ +import { mock } from "jest-mock-extended"; + +import { + ApiSettings, + IntegrationRequest, + TokenHeader, +} from "@bitwarden/common/tools/integration/rpc"; + +import { CreateForwardingEmailRpcDef, ForwarderConfiguration } from "../forwarder-configuration"; +import { ForwarderContext } from "../forwarder-context"; + +import { CreateForwardingAddressRpc } from "./create-forwarding-address"; + +describe("CreateForwardingAddressRpc", () => { + const createForwardingEmail = + mock<CreateForwardingEmailRpcDef<ApiSettings, IntegrationRequest>>(); + const requestor = mock<ForwarderConfiguration<ApiSettings>>({ + forwarder: { createForwardingEmail }, + }); + const context = mock<ForwarderContext<ApiSettings>>(); + + beforeEach(() => { + createForwardingEmail.url.mockReturnValue("https://httpbin.org/json"); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe("toRequest", () => { + it("constructs a request", () => { + const builder = new CreateForwardingAddressRpc(requestor, context); + + const result = builder.toRequest({ website: null }); + + expect(result.redirect).toEqual("manual"); + expect(result.cache).toEqual("no-store"); + expect(result.method).toEqual("POST"); + expect(result.headers.get("Content-Type")).toEqual("application/json"); + expect(result.headers.get("X-Requested-With")).toEqual("XMLHttpRequest"); + }); + + it("provides the request and context to the rpc definition functions", () => { + const builder = new CreateForwardingAddressRpc(requestor, context); + const request: IntegrationRequest = { website: null }; + + builder.toRequest(request); + + expect(requestor.authenticate).toHaveBeenCalledWith(request, context); + + expect(createForwardingEmail.url).toHaveBeenCalledWith(request, context); + expect(createForwardingEmail.body).toHaveBeenCalledWith(request, context); + }); + + it("stringifies the body", async () => { + createForwardingEmail.body.mockReturnValue({ foo: 1 }); + const builder = new CreateForwardingAddressRpc(requestor, context); + + const request = builder.toRequest({ website: null }); + + // extract the text from the body; it's wild there isn't + // a more clear way to do this + const result = await new Response(request.body).text(); + + expect(result).toEqual('{"foo":1}'); + }); + + it("omits the body", async () => { + // can't use the mock here because it defines a `body` function + // on `createForwardingEmail` + const requestor = { + authenticate() { + return undefined as TokenHeader; + }, + forwarder: { + createForwardingEmail: { + url() { + return "https://httpbin.org/json"; + }, + }, + }, + } as unknown as ForwarderConfiguration<ApiSettings>; + + const builder = new CreateForwardingAddressRpc(requestor, context); + + const result = builder.toRequest({ website: null }); + + expect(result.body).toBeNull(); + }); + }); + + describe("hasJsonPayload", () => { + it("forwards the call to the rpc definition with context", () => { + const builder = new CreateForwardingAddressRpc(requestor, context); + const response: Response = {} as any; + createForwardingEmail.hasJsonPayload.mockReturnValue(true); + + const result = builder.hasJsonPayload(response); + + expect(result).toBe(true); + expect(createForwardingEmail.hasJsonPayload).toHaveBeenCalledWith(response, context); + }); + }); + + describe("processJson", () => { + it("forwards the call to the rpc definition with context", () => { + const builder = new CreateForwardingAddressRpc(requestor, context); + const json = {} as any; + createForwardingEmail.processJson.mockReturnValue(["foo"]); + + const result = builder.processJson(json); + + expect(result).toEqual(["foo"]); + expect(createForwardingEmail.processJson).toHaveBeenCalledWith(json, context); + }); + }); +}); diff --git a/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts new file mode 100644 index 00000000000..210a7a1b21c --- /dev/null +++ b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts @@ -0,0 +1,64 @@ +import { IntegrationContext } from "@bitwarden/common/tools/integration"; +import { JsonRpc, IntegrationRequest, ApiSettings } from "@bitwarden/common/tools/integration/rpc"; + +import { ForwarderConfiguration } from "../forwarder-configuration"; +import { ForwarderContext } from "../forwarder-context"; + +export class CreateForwardingAddressRpc< + Settings extends ApiSettings, + Req extends IntegrationRequest = IntegrationRequest, +> implements JsonRpc<Req, string> +{ + constructor( + readonly requestor: ForwarderConfiguration<Settings>, + readonly context: ForwarderContext<Settings>, + ) {} + + private get createForwardingEmail() { + return this.requestor.forwarder.createForwardingEmail; + } + + toRequest(req: Req) { + const url = this.createForwardingEmail.url(req, this.context); + const token = this.requestor.authenticate(req, this.context as IntegrationContext<Settings>); + const body = this.body(req); + + const request = new Request(url, { + redirect: "manual", + cache: "no-store", + method: "POST", + headers: new Headers({ + ...token, + // X-Requested-With header required by some endpoints for + // detailed error descriptions (see #5565) + "X-Requested-With": "XMLHttpRequest", + "Content-Type": "application/json", + }), + body, + }); + + return request; + } + + private body(req: Req) { + const toBody = this.createForwardingEmail.body; + if (!toBody) { + return undefined; + } + + const body = toBody(req, this.context); + if (!body) { + return undefined; + } + + return JSON.stringify(body); + } + + hasJsonPayload(response: Response): boolean { + return this.createForwardingEmail.hasJsonPayload(response, this.context); + } + + processJson(json: any): [string?, string?] { + return this.createForwardingEmail.processJson(json, this.context); + } +} diff --git a/libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts b/libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts new file mode 100644 index 00000000000..1772bf9901c --- /dev/null +++ b/libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts @@ -0,0 +1,83 @@ +import { mock } from "jest-mock-extended"; + +import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; + +import { GetAccountIdRpcDef, ForwarderConfiguration } from "../forwarder-configuration"; +import { ForwarderContext } from "../forwarder-context"; + +import { GetAccountIdRpc } from "./get-account-id"; + +describe("GetAccountIdRpc", () => { + const getAccountId = mock<GetAccountIdRpcDef<ApiSettings, IntegrationRequest>>(); + const requestor = mock<ForwarderConfiguration<ApiSettings>>({ + forwarder: { getAccountId }, + }); + const context = mock<ForwarderContext<ApiSettings>>(); + + beforeEach(() => { + getAccountId.url.mockReturnValue("https://httpbin.org/json"); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe("toRequest", () => { + it("constructs a request", () => { + const builder = new GetAccountIdRpc(requestor, context); + + const result = builder.toRequest({ website: null }); + + expect(result.redirect).toEqual("manual"); + expect(result.cache).toEqual("no-store"); + expect(result.method).toEqual("GET"); + expect(result.headers.get("Content-Type")).toEqual("application/json"); + }); + + it("provides the request and context to the rpc definition functions", () => { + const builder = new GetAccountIdRpc(requestor, context); + const request: IntegrationRequest = { website: null }; + + builder.toRequest(request); + + expect(requestor.authenticate).toHaveBeenCalledWith(request, context); + + expect(getAccountId.url).toHaveBeenCalledWith(request, context); + }); + + it("omits the body", async () => { + const builder = new GetAccountIdRpc(requestor, context); + + const result = builder.toRequest({ website: null }); + + expect(result.body).toBeNull(); + expect(getAccountId.body).not.toHaveBeenCalled(); + }); + }); + + describe("hasJsonPayload", () => { + it("forwards the call to the rpc definition with context", () => { + const builder = new GetAccountIdRpc(requestor, context); + const response: Response = {} as any; + getAccountId.hasJsonPayload.mockReturnValue(true); + + const result = builder.hasJsonPayload(response); + + expect(result).toBe(true); + expect(getAccountId.hasJsonPayload).toHaveBeenCalledWith(response, context); + }); + }); + + describe("processJson", () => { + it("forwards the call to the rpc definition with context", () => { + const builder = new GetAccountIdRpc(requestor, context); + const json = {} as any; + getAccountId.processJson.mockReturnValue(["foo"]); + + const result = builder.processJson(json); + + expect(result).toEqual(["foo"]); + expect(getAccountId.processJson).toHaveBeenCalledWith(json, context); + }); + }); +}); diff --git a/libs/tools/generator/core/src/engine/rpc/get-account-id.ts b/libs/tools/generator/core/src/engine/rpc/get-account-id.ts new file mode 100644 index 00000000000..4e90df77ff0 --- /dev/null +++ b/libs/tools/generator/core/src/engine/rpc/get-account-id.ts @@ -0,0 +1,41 @@ +import { IntegrationContext } from "@bitwarden/common/tools/integration"; +import { JsonRpc, IntegrationRequest, ApiSettings } from "@bitwarden/common/tools/integration/rpc"; + +import { ForwarderConfiguration } from "../forwarder-configuration"; +import { ForwarderContext } from "../forwarder-context"; + +export class GetAccountIdRpc< + Settings extends ApiSettings, + Req extends IntegrationRequest = IntegrationRequest, +> implements JsonRpc<Req, string> +{ + constructor( + readonly requestor: ForwarderConfiguration<Settings>, + readonly context: ForwarderContext<Settings>, + ) {} + + hasJsonPayload(response: Response) { + return this.requestor.forwarder.getAccountId.hasJsonPayload(response, this.context); + } + + processJson(json: any) { + return this.requestor.forwarder.getAccountId.processJson(json, this.context); + } + + toRequest(req: Req) { + const url = this.requestor.forwarder.getAccountId.url(req, this.context); + const token = this.requestor.authenticate(req, this.context as IntegrationContext<Settings>); + + const request = new Request(url, { + redirect: "manual", + cache: "no-store", + method: "GET", + headers: new Headers({ + ...token, + "Content-Type": "application/json", + }), + }); + + return request; + } +} diff --git a/libs/tools/generator/core/src/engine/rpc/index.ts b/libs/tools/generator/core/src/engine/rpc/index.ts new file mode 100644 index 00000000000..8fc16321af6 --- /dev/null +++ b/libs/tools/generator/core/src/engine/rpc/index.ts @@ -0,0 +1,2 @@ +export * from "./create-forwarding-address"; +export * from "./get-account-id"; diff --git a/libs/tools/generator/core/src/engine/settings.ts b/libs/tools/generator/core/src/engine/settings.ts new file mode 100644 index 00000000000..2a9af5d2d65 --- /dev/null +++ b/libs/tools/generator/core/src/engine/settings.ts @@ -0,0 +1,20 @@ +/** Api configuration for forwarders that support custom domains. */ +export type EmailDomainSettings = { + /** The domain part of the generated email address. + * @remarks The domain should be authorized by the forwarder before + * submitting a request through bitwarden. + * @example If the domain is `domain.io` and the generated username + * is `jd`, then the generated email address will be `jd@domain.io` + */ + domain: string; +}; + +/** Api configuration for forwarders that support custom email parts. */ +export type EmailPrefixSettings = { + /** A prefix joined to the generated email address' username. + * @example If the prefix is `foo`, the generated username is `bar`, + * and the domain is `domain.io`, then the generated email address is ` + * then the generated username is `foobar@domain.io`. + */ + prefix: string; +}; diff --git a/libs/tools/generator/core/src/index.ts b/libs/tools/generator/core/src/index.ts index c01faaece92..330bb64f590 100644 --- a/libs/tools/generator/core/src/index.ts +++ b/libs/tools/generator/core/src/index.ts @@ -2,6 +2,7 @@ export * from "./abstractions"; export * from "./data"; export { createRandomizer } from "./factories"; export * as engine from "./engine"; +export * as integration from "./integration"; export * as policies from "./policies"; export * as rx from "./rx"; export * as services from "./services"; diff --git a/libs/tools/generator/core/src/integration/addy-io.spec.ts b/libs/tools/generator/core/src/integration/addy-io.spec.ts new file mode 100644 index 00000000000..9c816330616 --- /dev/null +++ b/libs/tools/generator/core/src/integration/addy-io.spec.ts @@ -0,0 +1,83 @@ +import { mock } from "jest-mock-extended"; + +import { ForwarderContext } from "../engine"; + +import { AddyIo, AddyIoSettings } from "./addy-io"; + +describe("Addy.io forwarder", () => { + const context = mock<ForwarderContext<AddyIoSettings>>(); + + afterEach(() => { + jest.resetAllMocks(); + }); + + describe("authenticate", () => { + it("returns a bearer header with the token", () => { + context.authenticationToken.mockReturnValue("token"); + const result = AddyIo.authenticate(null, context); + + expect(result).toEqual({ Authorization: "Bearer token" }); + expect(context.authenticationToken).toHaveBeenCalled(); + }); + }); + + describe("settings", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = AddyIo.forwarder.settings.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("importBuffer", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = AddyIo.forwarder.importBuffer.options.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("createForwardingEmail", () => { + describe("url", () => { + it("returns the alias path", () => { + context.baseUrl.mockReturnValue(""); + + const result = AddyIo.forwarder.createForwardingEmail.url(null, context); + + expect(result).toEqual("/api/v1/aliases"); + }); + }); + + describe("body", () => { + it("returns the alias path", () => { + context.emailDomain.mockReturnValue("domain"); + context.generatedBy.mockReturnValue("generated by"); + + const result = AddyIo.forwarder.createForwardingEmail.body(null, context); + + expect(result).toEqual({ + domain: "domain", + description: "generated by", + }); + }); + }); + + describe("hasJsonPayload", () => { + it.each([[200], [201]])("returns true when the status is $%i", (status) => { + const result = AddyIo.forwarder.createForwardingEmail.hasJsonPayload( + { status } as Response, + context, + ); + expect(result).toBeTruthy(); + }); + }); + + describe("processJson", () => { + it("should read the email from the response", () => { + const json = { data: { email: "foo@example.com" } }; + const result = AddyIo.forwarder.createForwardingEmail.processJson(json, context); + expect(result).toEqual(["foo@example.com"]); + }); + }); + }); +}); diff --git a/libs/tools/generator/core/src/integration/addy-io.ts b/libs/tools/generator/core/src/integration/addy-io.ts new file mode 100644 index 00000000000..8f594827e95 --- /dev/null +++ b/libs/tools/generator/core/src/integration/addy-io.ts @@ -0,0 +1,73 @@ +import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; +import { IntegrationContext, IntegrationId } from "@bitwarden/common/tools/integration"; +import { + ApiSettings, + IntegrationRequest, + SelfHostedApiSettings, +} from "@bitwarden/common/tools/integration/rpc"; +import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + +import { ForwarderConfiguration, ForwarderContext, EmailDomainSettings } from "../engine"; +import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration"; +import { EmailDomainOptions, SelfHostedApiOptions } from "../types"; + +// integration types +export type AddyIoSettings = SelfHostedApiSettings & EmailDomainSettings; +export type AddyIoOptions = SelfHostedApiOptions & EmailDomainOptions; +export type AddyIoConfiguration = ForwarderConfiguration<AddyIoSettings>; + +// default values +const defaultSettings = Object.freeze({ + token: "", + domain: "", +}); + +// supported RPC calls +const createForwardingEmail = Object.freeze({ + url(_request: IntegrationRequest, context: ForwarderContext<AddyIoSettings>) { + return context.baseUrl() + "/api/v1/aliases"; + }, + body(request: IntegrationRequest, context: ForwarderContext<AddyIoSettings>) { + return { + domain: context.emailDomain(), + description: context.generatedBy(request), + }; + }, + hasJsonPayload(response: Response) { + return response.status === 200 || response.status === 201; + }, + processJson(json: any) { + return [json?.data?.email]; + }, +} as CreateForwardingEmailRpcDef<AddyIoSettings>); + +// forwarder configuration +const forwarder = Object.freeze({ + defaultSettings, + settings: new UserKeyDefinition<AddyIoSettings>(GENERATOR_DISK, "addyIoForwarder", { + deserializer: (value) => value, + clearOn: [], + }), + importBuffer: new BufferedKeyDefinition<AddyIoSettings>(GENERATOR_DISK, "addyIoBuffer", { + deserializer: (value) => value, + clearOn: ["logout"], + }), + createForwardingEmail, +} as const); + +export const AddyIo = Object.freeze({ + // integration + id: "anonaddy" as IntegrationId, + name: "Addy.io", + extends: ["forwarder"], + + // hosting + selfHost: "maybe", + baseUrl: "https://app.addy.io", + authenticate(_request: IntegrationRequest, context: IntegrationContext<ApiSettings>) { + return { Authorization: "Bearer " + context.authenticationToken() }; + }, + + // extensions + forwarder, +} as AddyIoConfiguration); diff --git a/libs/tools/generator/core/src/integration/duck-duck-go.spec.ts b/libs/tools/generator/core/src/integration/duck-duck-go.spec.ts new file mode 100644 index 00000000000..880be0936b8 --- /dev/null +++ b/libs/tools/generator/core/src/integration/duck-duck-go.spec.ts @@ -0,0 +1,78 @@ +import { mock } from "jest-mock-extended"; + +import { ForwarderContext } from "../engine"; + +import { DuckDuckGo, DuckDuckGoSettings } from "./duck-duck-go"; + +describe("DuckDuckGo forwarder", () => { + const context = mock<ForwarderContext<DuckDuckGoSettings>>(); + + afterEach(() => { + jest.resetAllMocks(); + }); + + describe("authenticate", () => { + it("returns a bearer header with the token", () => { + context.authenticationToken.mockReturnValue("token"); + + const result = DuckDuckGo.authenticate(null, context); + + expect(result).toEqual({ Authorization: "Bearer token" }); + expect(context.authenticationToken).toHaveBeenCalled(); + }); + }); + + describe("settings", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = DuckDuckGo.forwarder.settings.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("importBuffer", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = DuckDuckGo.forwarder.importBuffer.options.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("createForwardingEmail", () => { + describe("url", () => { + it("returns the alias path", () => { + context.baseUrl.mockReturnValue(""); + + const result = DuckDuckGo.forwarder.createForwardingEmail.url(null, context); + + expect(result).toEqual("/email/addresses"); + }); + }); + + describe("body", () => { + it("returns undefined", () => { + const result = DuckDuckGo.forwarder.createForwardingEmail.body(null, context); + + expect(result).not.toBeDefined(); + }); + }); + + describe("hasJsonPayload", () => { + it.each([[200], [201]])("returns true when the status is $%i", (status) => { + const result = DuckDuckGo.forwarder.createForwardingEmail.hasJsonPayload( + { status } as Response, + context, + ); + expect(result).toBeTruthy(); + }); + }); + + describe("processJson", () => { + it("should read the email from the response", () => { + const json = { address: "foo" }; + const result = DuckDuckGo.forwarder.createForwardingEmail.processJson(json, context); + expect(result).toEqual(["foo@duck.com"]); + }); + }); + }); +}); diff --git a/libs/tools/generator/core/src/integration/duck-duck-go.ts b/libs/tools/generator/core/src/integration/duck-duck-go.ts new file mode 100644 index 00000000000..0c13ac6b632 --- /dev/null +++ b/libs/tools/generator/core/src/integration/duck-duck-go.ts @@ -0,0 +1,61 @@ +import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; +import { IntegrationContext, IntegrationId } from "@bitwarden/common/tools/integration"; +import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; +import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + +import { ForwarderConfiguration, ForwarderContext } from "../engine"; +import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration"; +import { ApiOptions } from "../types"; + +// integration types +export type DuckDuckGoSettings = ApiSettings; +export type DuckDuckGoOptions = ApiOptions; +export type DuckDuckGoConfiguration = ForwarderConfiguration<DuckDuckGoSettings>; + +// default values +const defaultSettings = Object.freeze({ + token: "", +}); + +// supported RPC calls +const createForwardingEmail = Object.freeze({ + url(_request: IntegrationRequest, context: ForwarderContext<DuckDuckGoSettings>) { + return context.baseUrl() + "/email/addresses"; + }, + body(_request: IntegrationRequest, _context: ForwarderContext<DuckDuckGoSettings>) { + return undefined; + }, + hasJsonPayload(response: Response) { + return response.status === 200 || response.status === 201; + }, + processJson(json: any) { + return [`${json.address}@duck.com`]; + }, +} as CreateForwardingEmailRpcDef<DuckDuckGoSettings>); + +// forwarder configuration +const forwarder = Object.freeze({ + defaultSettings, + settings: new UserKeyDefinition<DuckDuckGoSettings>(GENERATOR_DISK, "duckDuckGoForwarder", { + deserializer: (value) => value, + clearOn: [], + }), + importBuffer: new BufferedKeyDefinition<DuckDuckGoSettings>(GENERATOR_DISK, "duckDuckGoBuffer", { + deserializer: (value) => value, + clearOn: ["logout"], + }), + createForwardingEmail, +} as const); + +// integration-wide configuration +export const DuckDuckGo = Object.freeze({ + id: "duckduckgo" as IntegrationId, + name: "DuckDuckGo", + baseUrl: "https://quack.duckduckgo.com/api", + selfHost: "never", + extends: ["forwarder"], + authenticate(_request: IntegrationRequest, context: IntegrationContext<ApiSettings>) { + return { Authorization: "Bearer " + context.authenticationToken() }; + }, + forwarder, +} as DuckDuckGoConfiguration); diff --git a/libs/tools/generator/core/src/integration/fastmail.spec.ts b/libs/tools/generator/core/src/integration/fastmail.spec.ts new file mode 100644 index 00000000000..f7b200a30e0 --- /dev/null +++ b/libs/tools/generator/core/src/integration/fastmail.spec.ts @@ -0,0 +1,215 @@ +import { mock } from "jest-mock-extended"; + +import { ForwarderContext } from "../engine"; + +import { Fastmail, FastmailSettings } from "./fastmail"; + +describe("Fastmail forwarder", () => { + const context = mock<ForwarderContext<FastmailSettings>>(); + + afterEach(() => { + jest.resetAllMocks(); + }); + + describe("authenticate", () => { + it("returns a bearer header with the token", () => { + context.authenticationToken.mockReturnValue("token"); + + const result = Fastmail.authenticate(null, context); + + expect(result).toEqual({ Authorization: "Bearer token" }); + expect(context.authenticationToken).toHaveBeenCalled(); + }); + }); + + describe("settings", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = Fastmail.forwarder.settings.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("importBuffer", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = Fastmail.forwarder.importBuffer.options.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("getAccountId", () => { + describe("url", () => { + it("returns the alias path", () => { + context.baseUrl.mockReturnValue(""); + + const result = Fastmail.forwarder.getAccountId.url(null, context); + + expect(result).toEqual("/jmap/session"); + }); + }); + + describe("hasJsonPayload", () => { + it.each([[200]])("returns true when the status is $%i", (status) => { + const result = Fastmail.forwarder.getAccountId.hasJsonPayload( + { status } as Response, + context, + ); + expect(result).toBeTruthy(); + }); + }); + + describe("processJson", () => { + it("looks up an account id", () => { + const json = { + primaryAccounts: { + "https://www.fastmail.com/dev/maskedemail": "some id", + }, + }; + + const result = Fastmail.forwarder.getAccountId.processJson(json, context); + expect(result).toEqual(["some id"]); + }); + + it("returns a cause when account id is missing", () => { + context.missingAccountIdCause.mockReturnValue("cause"); + const json = { + primaryAccounts: { + "https://www.fastmail.com/dev/maskedemail": null as string, + }, + }; + + const result = Fastmail.forwarder.getAccountId.processJson(json, context); + expect(result).toEqual([undefined, "cause"]); + }); + + it("returns a cause when masked mail account is missing", () => { + context.missingAccountIdCause.mockReturnValue("cause"); + const json = { primaryAccounts: {} }; + + const result = Fastmail.forwarder.getAccountId.processJson(json, context); + expect(result).toEqual([undefined, "cause"]); + }); + + it("returns a cause when all accounts are missing", () => { + context.missingAccountIdCause.mockReturnValue("cause"); + const json = { primaryAccounts: null as any }; + + const result = Fastmail.forwarder.getAccountId.processJson(json, context); + expect(result).toEqual([undefined, "cause"]); + }); + }); + }); + + describe("createForwardingEmail", () => { + describe("url", () => { + it("returns the alias path", () => { + context.baseUrl.mockReturnValue(""); + + const result = Fastmail.forwarder.createForwardingEmail.url(null, context); + + expect(result).toEqual("/jmap/api/"); + }); + }); + + describe("body", () => { + it("creates a request body", () => { + context.website.mockReturnValue("website"); + const request = { accountId: "accountId", website: "" }; + + const result = Fastmail.forwarder.createForwardingEmail.body(request, context); + const methodCall = result.methodCalls[0][1]; + + expect(methodCall.accountId).toEqual("accountId"); + expect(methodCall.create["new-masked-email"].forDomain).toEqual("website"); + }); + }); + + describe("hasJsonPayload", () => { + it.each([[200]])("returns true when the status is $%i", (status) => { + const result = Fastmail.forwarder.createForwardingEmail.hasJsonPayload( + { status } as Response, + context, + ); + expect(result).toBeTruthy(); + }); + }); + + describe("processJson", () => { + it("returns the generated email address", () => { + const body = { + methodResponses: [ + [ + "MaskedEmail/set", + { + created: { + "new-masked-email": { + email: "jdoe@example.com", + }, + }, + }, + ], + ], + }; + + const result = Fastmail.forwarder.createForwardingEmail.processJson(body, context); + + expect(result).toEqual(["jdoe@example.com"]); + }); + + it("returns a forwarder error if masked email creation fails", () => { + const notCreatedBody = { + methodResponses: [ + [ + "MaskedEmail/set", + { + notCreated: { "new-masked-email": { description: "It turned inside out!" } }, + }, + ], + ], + }; + + const notCreatedResult = Fastmail.forwarder.createForwardingEmail.processJson( + notCreatedBody, + context, + ); + + expect(notCreatedResult).toEqual([undefined, "It turned inside out!"]); + + const generalErrorBody = { + methodResponses: [["error", { description: "And then it exploded!" }]], + }; + + const generalErrorResult = Fastmail.forwarder.createForwardingEmail.processJson( + generalErrorBody, + context, + ); + + expect(generalErrorResult).toEqual([undefined, "And then it exploded!"]); + }); + + it.each([ + null, + [], + [[]], + [["MaskedEmail/not-a-real-op"]], + [["MaskedEmail/set", null]], + [["MaskedEmail/set", { created: null }]], + [["MaskedEmail/set", { created: { "new-masked-email": null } }]], + [["MaskedEmail/set", { notCreated: null }]], + [["MaskedEmail/set", { notCreated: { "new-masked-email": null } }]], + ])("returns undefined if the jmap request is malformed (=%p)", (response: any) => { + const generalErrorBody = { + methodResponses: response, + }; + + const result = Fastmail.forwarder.createForwardingEmail.processJson( + generalErrorBody, + context, + ); + + expect(result).toBeUndefined(); + }); + }); + }); +}); diff --git a/libs/tools/generator/core/src/integration/fastmail.ts b/libs/tools/generator/core/src/integration/fastmail.ts new file mode 100644 index 00000000000..0987540e036 --- /dev/null +++ b/libs/tools/generator/core/src/integration/fastmail.ts @@ -0,0 +1,127 @@ +import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; +import { IntegrationContext, IntegrationId } from "@bitwarden/common/tools/integration"; +import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; +import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + +import { + ForwarderConfiguration, + ForwarderContext, + EmailDomainSettings, + AccountRequest, + EmailPrefixSettings, +} from "../engine"; +import { CreateForwardingEmailRpcDef, GetAccountIdRpcDef } from "../engine/forwarder-configuration"; +import { ApiOptions, EmailPrefixOptions } from "../types"; + +// integration types +export type FastmailSettings = ApiSettings & EmailPrefixSettings & EmailDomainSettings; +export type FastmailOptions = ApiOptions & EmailPrefixOptions & AccountRequest; +export type FastmailRequest = IntegrationRequest & AccountRequest; +export type FastmailConfiguration = ForwarderConfiguration<FastmailSettings, FastmailRequest>; + +// default values +const defaultSettings = Object.freeze({ + domain: "", + prefix: "", + token: "", +}); + +// supported RPC calls +const getAccountId = Object.freeze({ + url(_request: IntegrationRequest, context: ForwarderContext<FastmailSettings>) { + // cannot use "/.well-known/jmap" because integration RPCs + // never follow redirects + return context.baseUrl() + "/jmap/session"; + }, + hasJsonPayload(response: Response) { + return response.status === 200; + }, + processJson(json: any, context: ForwarderContext<FastmailSettings>) { + const result = json.primaryAccounts?.["https://www.fastmail.com/dev/maskedemail"] ?? undefined; + + return [result, result ? undefined : context.missingAccountIdCause()]; + }, +} as GetAccountIdRpcDef<FastmailSettings>); + +const createForwardingEmail = Object.freeze({ + url(_request: IntegrationRequest, context: ForwarderContext<FastmailSettings>) { + return context.baseUrl() + "/jmap/api/"; + }, + body(request: FastmailRequest, context: ForwarderContext<FastmailSettings>) { + const body = { + using: ["https://www.fastmail.com/dev/maskedemail", "urn:ietf:params:jmap:core"], + methodCalls: [ + [ + "MaskedEmail/set", + { + accountId: request.accountId, + create: { + "new-masked-email": { + state: "enabled", + description: "", + forDomain: context.website(request), + emailPrefix: "", + }, + }, + }, + "0", + ], + ], + }; + + return body; + }, + hasJsonPayload(response: Response) { + return response.status === 200; + }, + processJson(json: any): [string?, string?] { + if ( + json.methodResponses != null && + json.methodResponses.length > 0 && + json.methodResponses[0].length > 0 + ) { + if (json.methodResponses[0][0] === "MaskedEmail/set") { + if (json.methodResponses[0][1]?.created?.["new-masked-email"] != null) { + const email: string = json.methodResponses[0][1]?.created?.["new-masked-email"]?.email; + return [email]; + } + if (json.methodResponses[0][1]?.notCreated?.["new-masked-email"] != null) { + const errorDescription: string = + json.methodResponses[0][1]?.notCreated?.["new-masked-email"]?.description; + return [undefined, errorDescription]; + } + } else if (json.methodResponses[0][0] === "error") { + const errorDescription: string = json.methodResponses[0][1]?.description; + return [undefined, errorDescription]; + } + } + }, +} as CreateForwardingEmailRpcDef<FastmailSettings, FastmailRequest>); + +// forwarder configuration +const forwarder = Object.freeze({ + defaultSettings, + settings: new UserKeyDefinition<FastmailSettings>(GENERATOR_DISK, "fastmailForwarder", { + deserializer: (value) => value, + clearOn: [], + }), + importBuffer: new BufferedKeyDefinition<FastmailSettings>(GENERATOR_DISK, "fastmailBuffer", { + deserializer: (value) => value, + clearOn: ["logout"], + }), + createForwardingEmail, + getAccountId, +} as const); + +// integration-wide configuration +export const Fastmail = Object.freeze({ + id: "fastmail" as IntegrationId, + name: "Fastmail", + baseUrl: "https://api.fastmail.com", + selfHost: "maybe", + extends: ["forwarder"], + authenticate(_request: IntegrationRequest, context: IntegrationContext<ApiSettings>) { + return { Authorization: "Bearer " + context.authenticationToken() }; + }, + forwarder, +} as FastmailConfiguration); diff --git a/libs/tools/generator/core/src/integration/firefox-relay.spec.ts b/libs/tools/generator/core/src/integration/firefox-relay.spec.ts new file mode 100644 index 00000000000..ed487b7f49f --- /dev/null +++ b/libs/tools/generator/core/src/integration/firefox-relay.spec.ts @@ -0,0 +1,85 @@ +import { mock } from "jest-mock-extended"; + +import { ForwarderContext } from "../engine"; + +import { FirefoxRelay, FirefoxRelaySettings } from "./firefox-relay"; + +describe("Firefox Relay forwarder", () => { + const context = mock<ForwarderContext<FirefoxRelaySettings>>(); + + afterEach(() => { + jest.resetAllMocks(); + }); + + describe("authenticate", () => { + it("returns a token header", () => { + context.authenticationToken.mockReturnValue("token"); + + const result = FirefoxRelay.authenticate(null, context); + + expect(result).toEqual({ Authorization: "Token token" }); + expect(context.authenticationToken).toHaveBeenCalled(); + }); + }); + + describe("settings", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = FirefoxRelay.forwarder.settings.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("importBuffer", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = FirefoxRelay.forwarder.importBuffer.options.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("createForwardingEmail", () => { + describe("url", () => { + it("returns the alias path", () => { + context.baseUrl.mockReturnValue(""); + + const result = FirefoxRelay.forwarder.createForwardingEmail.url(null, context); + + expect(result).toEqual("/v1/relayaddresses/"); + }); + }); + + describe("body", () => { + it("returns the alias path", () => { + context.website.mockReturnValue("website"); + context.generatedBy.mockReturnValue("generated by"); + + const result = FirefoxRelay.forwarder.createForwardingEmail.body(null, context); + + expect(result).toEqual({ + enabled: true, + generated_for: "website", + description: "generated by", + }); + }); + }); + + describe("hasJsonPayload", () => { + it.each([[200], [201]])("returns true when the status is $%i", (status) => { + const result = FirefoxRelay.forwarder.createForwardingEmail.hasJsonPayload( + { status } as Response, + context, + ); + expect(result).toBeTruthy(); + }); + }); + + describe("processJson", () => { + it("should read the email from the response", () => { + const json = { full_address: "foo@example.com" }; + const result = FirefoxRelay.forwarder.createForwardingEmail.processJson(json, context); + expect(result).toEqual(["foo@example.com"]); + }); + }); + }); +}); diff --git a/libs/tools/generator/core/src/integration/firefox-relay.ts b/libs/tools/generator/core/src/integration/firefox-relay.ts new file mode 100644 index 00000000000..4feb8a0bd99 --- /dev/null +++ b/libs/tools/generator/core/src/integration/firefox-relay.ts @@ -0,0 +1,69 @@ +import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; +import { IntegrationContext, IntegrationId } from "@bitwarden/common/tools/integration"; +import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; +import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + +import { ForwarderConfiguration, ForwarderContext } from "../engine"; +import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration"; +import { ApiOptions } from "../types"; + +// integration types +export type FirefoxRelaySettings = ApiSettings; +export type FirefoxRelayOptions = ApiOptions; +export type FirefoxRelayConfiguration = ForwarderConfiguration<FirefoxRelaySettings>; + +// default values +const defaultSettings = Object.freeze({ + token: "", +} as FirefoxRelaySettings); + +// supported RPC calls +const createForwardingEmail = Object.freeze({ + url(_request: IntegrationRequest, context: ForwarderContext<FirefoxRelaySettings>) { + return context.baseUrl() + "/v1/relayaddresses/"; + }, + body(request: IntegrationRequest, context: ForwarderContext<FirefoxRelaySettings>) { + return { + enabled: true, + generated_for: context.website(request), + description: context.generatedBy(request), + }; + }, + hasJsonPayload(response: Response) { + return response.status === 200 || response.status === 201; + }, + processJson(json: any) { + return [json.full_address]; + }, +} as CreateForwardingEmailRpcDef<FirefoxRelaySettings>); + +// forwarder configuration +const forwarder = Object.freeze({ + defaultSettings, + settings: new UserKeyDefinition<FirefoxRelaySettings>(GENERATOR_DISK, "firefoxRelayForwarder", { + deserializer: (value) => value, + clearOn: [], + }), + importBuffer: new BufferedKeyDefinition<FirefoxRelaySettings>( + GENERATOR_DISK, + "firefoxRelayBuffer", + { + deserializer: (value) => value, + clearOn: ["logout"], + }, + ), + createForwardingEmail, +} as const); + +// integration-wide configuration +export const FirefoxRelay = Object.freeze({ + id: "firefoxrelay" as IntegrationId, + name: "Firefox Relay", + baseUrl: "https://relay.firefox.com/api", + selfHost: "never", + extends: ["forwarder"], + authenticate(_request: IntegrationRequest, context: IntegrationContext<ApiSettings>) { + return { Authorization: "Token " + context.authenticationToken() }; + }, + forwarder, +} as FirefoxRelayConfiguration); diff --git a/libs/tools/generator/core/src/integration/forward-email.spec.ts b/libs/tools/generator/core/src/integration/forward-email.spec.ts new file mode 100644 index 00000000000..87ae5d2a570 --- /dev/null +++ b/libs/tools/generator/core/src/integration/forward-email.spec.ts @@ -0,0 +1,96 @@ +import { mock } from "jest-mock-extended"; + +import { ForwarderContext } from "../engine"; + +import { ForwardEmail, ForwardEmailSettings } from "./forward-email"; + +describe("Addy.io forwarder", () => { + const context = mock<ForwarderContext<ForwardEmailSettings>>(); + + afterEach(() => { + jest.resetAllMocks(); + }); + + describe("authenticate", () => { + it("returns a bearer header with the token", () => { + context.authenticationToken.mockReturnValue("token"); + + const result = ForwardEmail.authenticate(null, context); + + expect(result).toEqual({ Authorization: "Basic token" }); + expect(context.authenticationToken).toHaveBeenCalledWith({ base64: true, suffix: ":" }); + }); + }); + + describe("settings", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = ForwardEmail.forwarder.settings.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("importBuffer", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = ForwardEmail.forwarder.importBuffer.options.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("createForwardingEmail", () => { + describe("url", () => { + it("returns the alias path", () => { + context.baseUrl.mockReturnValue(""); + context.emailDomain.mockReturnValue("email domain"); + + const result = ForwardEmail.forwarder.createForwardingEmail.url(null, context); + + expect(result).toEqual("/v1/domains/email domain/aliases"); + }); + }); + + describe("body", () => { + it("returns the alias path", () => { + context.website.mockReturnValue("website"); + context.generatedBy.mockReturnValue("generated by"); + + const result = ForwardEmail.forwarder.createForwardingEmail.body(null, context); + + expect(result).toEqual({ + labels: "website", + description: "generated by", + }); + }); + }); + + describe("hasJsonPayload", () => { + it.each([[200], [201]])("returns true when the status is $%i", (status) => { + const result = ForwardEmail.forwarder.createForwardingEmail.hasJsonPayload( + { status } as Response, + context, + ); + expect(result).toBeTruthy(); + }); + }); + + describe("processJson", () => { + it("should read the email from the response", () => { + const json = { name: "foo", domain: { name: "example.com" } }; + + const result = ForwardEmail.forwarder.createForwardingEmail.processJson(json, context); + + expect(result).toEqual(["foo@example.com"]); + }); + + it("should use the domain from the request when it is not specified", () => { + context.emailDomain.mockReturnValue("example.com"); + const json = { name: "foo" }; + + const result = ForwardEmail.forwarder.createForwardingEmail.processJson(json, context); + + expect(result).toEqual(["foo@example.com"]); + }); + }); + }); +}); diff --git a/libs/tools/generator/core/src/integration/forward-email.ts b/libs/tools/generator/core/src/integration/forward-email.ts new file mode 100644 index 00000000000..c4ef21d9d30 --- /dev/null +++ b/libs/tools/generator/core/src/integration/forward-email.ts @@ -0,0 +1,76 @@ +import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; +import { IntegrationContext, IntegrationId } from "@bitwarden/common/tools/integration"; +import { ApiSettings, IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; +import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + +import { ForwarderConfiguration, ForwarderContext, EmailDomainSettings } from "../engine"; +import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration"; +import { ApiOptions, EmailDomainOptions } from "../types"; + +// integration types +export type ForwardEmailSettings = ApiSettings & EmailDomainSettings; +export type ForwardEmailOptions = ApiOptions & EmailDomainOptions; +export type ForwardEmailConfiguration = ForwarderConfiguration<ForwardEmailSettings>; + +// default values +const defaultSettings = Object.freeze({ + token: "", + domain: "", +}); + +// supported RPC calls +const createForwardingEmail = Object.freeze({ + url(_request: IntegrationRequest, context: ForwarderContext<ForwardEmailSettings>) { + const domain = context.emailDomain(); + return context.baseUrl() + `/v1/domains/${domain}/aliases`; + }, + body(request: IntegrationRequest, context: ForwarderContext<ForwardEmailSettings>) { + return { + labels: context.website(request), + description: context.generatedBy(request), + }; + }, + hasJsonPayload(response: Response) { + return response.status === 200 || response.status === 201; + }, + processJson(json: any, context: ForwarderContext<ForwardEmailSettings>) { + const { name, domain } = json; + const domainPart = domain?.name ?? context.emailDomain(); + return [`${name}@${domainPart}`]; + }, +} as CreateForwardingEmailRpcDef<ForwardEmailSettings>); + +// forwarder configuration +const forwarder = Object.freeze({ + defaultSettings, + settings: new UserKeyDefinition<ForwardEmailSettings>(GENERATOR_DISK, "forwardEmailForwarder", { + deserializer: (value) => value, + clearOn: [], + }), + importBuffer: new BufferedKeyDefinition<ForwardEmailSettings>( + GENERATOR_DISK, + "forwardEmailBuffer", + { + deserializer: (value) => value, + clearOn: ["logout"], + }, + ), + createForwardingEmail, +} as const); + +export const ForwardEmail = Object.freeze({ + // integration metadata + id: "forwardemail" as IntegrationId, + name: "Forward Email", + extends: ["forwarder"], + + // service provider + selfHost: "never", + baseUrl: "https://api.forwardemail.net", + authenticate(_request: IntegrationRequest, context: IntegrationContext<ApiSettings>) { + return { Authorization: "Basic " + context.authenticationToken({ base64: true, suffix: ":" }) }; + }, + + // specialized configurations + forwarder, +} as ForwardEmailConfiguration); diff --git a/libs/tools/generator/core/src/integration/index.ts b/libs/tools/generator/core/src/integration/index.ts new file mode 100644 index 00000000000..1a8b6cb8c57 --- /dev/null +++ b/libs/tools/generator/core/src/integration/index.ts @@ -0,0 +1,6 @@ +export * from "./addy-io"; +export * from "./duck-duck-go"; +export * from "./fastmail"; +export * from "./firefox-relay"; +export * from "./forward-email"; +export * from "./simple-login"; diff --git a/libs/tools/generator/core/src/integration/simple-login.spec.ts b/libs/tools/generator/core/src/integration/simple-login.spec.ts new file mode 100644 index 00000000000..dc3b71f3a8d --- /dev/null +++ b/libs/tools/generator/core/src/integration/simple-login.spec.ts @@ -0,0 +1,92 @@ +import { mock } from "jest-mock-extended"; + +import { ForwarderContext } from "../engine"; + +import { SimpleLogin, SimpleLoginSettings } from "./simple-login"; + +describe("Addy.io forwarder", () => { + const context = mock<ForwarderContext<SimpleLoginSettings>>(); + + afterEach(() => { + jest.resetAllMocks(); + }); + + describe("authenticate", () => { + it("returns a bearer header with the token", () => { + context.authenticationToken.mockReturnValue("token"); + + const result = SimpleLogin.authenticate(null, context); + + expect(result).toEqual({ Authentication: "token" }); + expect(context.authenticationToken).toHaveBeenCalled(); + }); + }); + + describe("settings", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = SimpleLogin.forwarder.settings.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("importBuffer", () => { + it("should pass through deserialization", () => { + const value: any = {}; + const result = SimpleLogin.forwarder.importBuffer.options.deserializer(value); + expect(result).toBe(value); + }); + }); + + describe("createForwardingEmail", () => { + describe("url", () => { + it("returns the alias path", () => { + context.website.mockReturnValue(""); + context.baseUrl.mockReturnValue(""); + + const result = SimpleLogin.forwarder.createForwardingEmail.url(null, context); + + expect(result).toEqual("/api/alias/random/new"); + }); + + it("includes the website in the alias path", () => { + context.baseUrl.mockReturnValue(""); + context.website.mockReturnValue("website"); + + const result = SimpleLogin.forwarder.createForwardingEmail.url(null, context); + + expect(result).toEqual("/api/alias/random/new?hostname=website"); + }); + }); + + describe("body", () => { + it("returns the alias path", () => { + context.generatedBy.mockReturnValue("generated by"); + + const result = SimpleLogin.forwarder.createForwardingEmail.body(null, context); + + expect(result).toEqual({ + note: "generated by", + }); + }); + }); + + describe("hasJsonPayload", () => { + it.each([[200], [201]])("returns true when the status is $%i", (status) => { + const result = SimpleLogin.forwarder.createForwardingEmail.hasJsonPayload( + { status } as Response, + context, + ); + expect(result).toBeTruthy(); + }); + }); + + describe("processJson", () => { + it("should read the email from the response", () => { + const json = { alias: "foo@example.com" }; + const result = SimpleLogin.forwarder.createForwardingEmail.processJson(json, context); + expect(result).toEqual(["foo@example.com"]); + }); + }); + }); +}); diff --git a/libs/tools/generator/core/src/integration/simple-login.ts b/libs/tools/generator/core/src/integration/simple-login.ts new file mode 100644 index 00000000000..88730d0578e --- /dev/null +++ b/libs/tools/generator/core/src/integration/simple-login.ts @@ -0,0 +1,74 @@ +import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; +import { IntegrationContext, IntegrationId } from "@bitwarden/common/tools/integration"; +import { + ApiSettings, + IntegrationRequest, + SelfHostedApiSettings, +} from "@bitwarden/common/tools/integration/rpc"; +import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + +import { ForwarderConfiguration, ForwarderContext } from "../engine"; +import { CreateForwardingEmailRpcDef } from "../engine/forwarder-configuration"; +import { SelfHostedApiOptions } from "../types"; + +// integration types +export type SimpleLoginSettings = SelfHostedApiSettings; +export type SimpleLoginOptions = SelfHostedApiOptions; +export type SimpleLoginConfiguration = ForwarderConfiguration<SimpleLoginSettings>; + +// default values +const defaultSettings = Object.freeze({ + token: "", + domain: "", +}); + +// supported RPC calls +const createForwardingEmail = Object.freeze({ + url(request: IntegrationRequest, context: ForwarderContext<SimpleLoginSettings>) { + const endpoint = context.baseUrl() + "/api/alias/random/new"; + const hostname = context.website(request); + const url = hostname !== "" ? `${endpoint}?hostname=${hostname}` : endpoint; + + return url; + }, + body(request: IntegrationRequest, context: ForwarderContext<SimpleLoginSettings>) { + return { note: context.generatedBy(request) }; + }, + hasJsonPayload(response: Response) { + return response.status === 200 || response.status === 201; + }, + processJson(json: any) { + return [json?.alias]; + }, +} as CreateForwardingEmailRpcDef<SimpleLoginSettings>); + +// forwarder configuration +const forwarder = Object.freeze({ + defaultSettings, + settings: new UserKeyDefinition<SimpleLoginSettings>(GENERATOR_DISK, "simpleLoginForwarder", { + deserializer: (value) => value, + clearOn: [], + }), + importBuffer: new BufferedKeyDefinition<SimpleLoginSettings>( + GENERATOR_DISK, + "simpleLoginBuffer", + { + deserializer: (value) => value, + clearOn: ["logout"], + }, + ), + createForwardingEmail, +} as const); + +// integration-wide configuration +export const SimpleLogin = Object.freeze({ + id: "simplelogin" as IntegrationId, + name: "SimpleLogin", + selfHost: "maybe", + extends: ["forwarder"], + baseUrl: "https://app.simplelogin.io", + authenticate(_request: IntegrationRequest, context: IntegrationContext<ApiSettings>) { + return { Authentication: context.authenticationToken() }; + }, + forwarder, +} as SimpleLoginConfiguration); diff --git a/libs/tools/generator/core/src/strategies/catchall-generator-strategy.ts b/libs/tools/generator/core/src/strategies/catchall-generator-strategy.ts index 53769dfa308..2436ecc2632 100644 --- a/libs/tools/generator/core/src/strategies/catchall-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/catchall-generator-strategy.ts @@ -6,7 +6,7 @@ import { DefaultCatchallOptions } from "../data"; import { EmailCalculator, EmailRandomizer } from "../engine"; import { newDefaultEvaluator } from "../rx"; import { NoPolicy, CatchallGenerationOptions } from "../types"; -import { clone$PerUserId, sharedStateByUserId } from "../util"; +import { observe$PerUserId, sharedStateByUserId } from "../util"; import { CATCHALL_SETTINGS } from "./storage"; @@ -26,7 +26,7 @@ export class CatchallGeneratorStrategy // configuration durableState = sharedStateByUserId(CATCHALL_SETTINGS, this.stateProvider); - defaults$ = clone$PerUserId(this.defaultOptions); + defaults$ = observe$PerUserId(() => this.defaultOptions); toEvaluator = newDefaultEvaluator<CatchallGenerationOptions>(); readonly policy = PolicyType.PasswordGenerator; diff --git a/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.ts b/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.ts index 5d0711afdc6..83ed3b0d14e 100644 --- a/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/eff-username-generator-strategy.ts @@ -6,7 +6,7 @@ import { DefaultEffUsernameOptions, UsernameDigits } from "../data"; import { UsernameRandomizer } from "../engine"; import { newDefaultEvaluator } from "../rx"; import { EffUsernameGenerationOptions, NoPolicy } from "../types"; -import { clone$PerUserId, sharedStateByUserId } from "../util"; +import { observe$PerUserId, sharedStateByUserId } from "../util"; import { EFF_USERNAME_SETTINGS } from "./storage"; @@ -25,7 +25,7 @@ export class EffUsernameGeneratorStrategy // configuration durableState = sharedStateByUserId(EFF_USERNAME_SETTINGS, this.stateProvider); - defaults$ = clone$PerUserId(this.defaultOptions); + defaults$ = observe$PerUserId(() => this.defaultOptions); toEvaluator = newDefaultEvaluator<EffUsernameGenerationOptions>(); readonly policy = PolicyType.PasswordGenerator; diff --git a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts index 31c3145559f..51a5032a8f5 100644 --- a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts +++ b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.spec.ts @@ -7,41 +7,17 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { StateProvider } from "@bitwarden/common/platform/state"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { RestClient } from "@bitwarden/common/tools/integration/rpc"; import { BufferedState } from "@bitwarden/common/tools/state/buffered-state"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; import { FakeStateProvider, mockAccountServiceWith } from "../../../../../common/spec"; -import { DefaultDuckDuckGoOptions } from "../data"; +import { AddyIo, Fastmail, FirefoxRelay } from "../integration"; import { DefaultPolicyEvaluator } from "../policies"; -import { ApiOptions } from "../types"; import { ForwarderGeneratorStrategy } from "./forwarder-generator-strategy"; -import { DUCK_DUCK_GO_FORWARDER, DUCK_DUCK_GO_BUFFER } from "./storage"; - -class TestForwarder extends ForwarderGeneratorStrategy<ApiOptions> { - constructor( - encryptService: EncryptService, - keyService: CryptoService, - stateProvider: StateProvider, - ) { - super(encryptService, keyService, stateProvider, { website: null, token: "" }); - } - - get key() { - // arbitrary. - return DUCK_DUCK_GO_FORWARDER; - } - - get rolloverKey() { - return DUCK_DUCK_GO_BUFFER; - } - - defaults$ = (userId: UserId) => { - return of(DefaultDuckDuckGoOptions); - }; -} const SomeUser = "some user" as UserId; const AnotherUser = "another user" as UserId; @@ -56,6 +32,8 @@ describe("ForwarderGeneratorStrategy", () => { const encryptService = mock<EncryptService>(); const keyService = mock<CryptoService>(); const stateProvider = new FakeStateProvider(mockAccountServiceWith(SomeUser)); + const restClient = mock<RestClient>(); + const i18nService = mock<I18nService>(); beforeEach(() => { const keyAvailable = of({} as UserKey); @@ -68,7 +46,14 @@ describe("ForwarderGeneratorStrategy", () => { describe("durableState", () => { it("constructs a secret state", () => { - const strategy = new TestForwarder(encryptService, keyService, stateProvider); + const strategy = new ForwarderGeneratorStrategy( + AddyIo, + restClient, + i18nService, + encryptService, + keyService, + stateProvider, + ); const result = strategy.durableState(SomeUser); @@ -76,7 +61,14 @@ describe("ForwarderGeneratorStrategy", () => { }); it("returns the same secret state for a single user", () => { - const strategy = new TestForwarder(encryptService, keyService, stateProvider); + const strategy = new ForwarderGeneratorStrategy( + AddyIo, + restClient, + i18nService, + encryptService, + keyService, + stateProvider, + ); const firstResult = strategy.durableState(SomeUser); const secondResult = strategy.durableState(SomeUser); @@ -85,7 +77,14 @@ describe("ForwarderGeneratorStrategy", () => { }); it("returns a different secret state for a different user", () => { - const strategy = new TestForwarder(encryptService, keyService, stateProvider); + const strategy = new ForwarderGeneratorStrategy( + AddyIo, + restClient, + i18nService, + encryptService, + keyService, + stateProvider, + ); const firstResult = strategy.durableState(SomeUser); const secondResult = strategy.durableState(AnotherUser); @@ -98,7 +97,14 @@ describe("ForwarderGeneratorStrategy", () => { it.each([[[]], [null], [undefined], [[SomePolicy]], [[SomePolicy, SomePolicy]]])( "should map any input (= %p) to the default policy evaluator", async (policies) => { - const strategy = new TestForwarder(encryptService, keyService, stateProvider); + const strategy = new ForwarderGeneratorStrategy( + AddyIo, + restClient, + i18nService, + encryptService, + keyService, + stateProvider, + ); const evaluator$ = of(policies).pipe(strategy.toEvaluator()); const evaluator = await firstValueFrom(evaluator$); @@ -107,4 +113,39 @@ describe("ForwarderGeneratorStrategy", () => { }, ); }); + + describe("generate", () => { + it("issues a remote procedure request to create the forwarding address", async () => { + restClient.fetchJson.mockResolvedValue("jdoe@example.com"); + const strategy = new ForwarderGeneratorStrategy( + FirefoxRelay, + restClient, + i18nService, + encryptService, + keyService, + stateProvider, + ); + + const result = await strategy.generate({ website: null }); + + expect(result).toEqual("jdoe@example.com"); + }); + + it("issues a remote procedure request to look up the account id before creating the forwarding address", async () => { + restClient.fetchJson.mockResolvedValue("some account id"); + restClient.fetchJson.mockResolvedValue("jdoe@example.com"); + const strategy = new ForwarderGeneratorStrategy( + Fastmail, + restClient, + i18nService, + encryptService, + keyService, + stateProvider, + ); + + const result = await strategy.generate({ website: null, prefix: "", domain: "example.com" }); + + expect(result).toEqual("jdoe@example.com"); + }); + }); }); diff --git a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts index 4dbabac1c71..b4fb4aabc6b 100644 --- a/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts @@ -1,32 +1,39 @@ import { map } from "rxjs"; +import { Jsonify } from "type-fest"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { SingleUserState, StateProvider } from "@bitwarden/common/platform/state"; import { - SingleUserState, - StateProvider, - UserKeyDefinition, -} from "@bitwarden/common/platform/state"; -import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; + ApiSettings, + IntegrationRequest, + RestClient, +} from "@bitwarden/common/tools/integration/rpc"; import { BufferedState } from "@bitwarden/common/tools/state/buffered-state"; import { PaddedDataPacker } from "@bitwarden/common/tools/state/padded-data-packer"; -import { SecretClassifier } from "@bitwarden/common/tools/state/secret-classifier"; import { SecretKeyDefinition } from "@bitwarden/common/tools/state/secret-key-definition"; import { SecretState } from "@bitwarden/common/tools/state/secret-state"; import { UserKeyEncryptor } from "@bitwarden/common/tools/state/user-key-encryptor"; import { UserId } from "@bitwarden/common/types/guid"; import { GeneratorStrategy } from "../abstractions"; +import { ForwarderConfiguration, AccountRequest, ForwarderContext } from "../engine"; +import { CreateForwardingAddressRpc } from "../engine/rpc/create-forwarding-address"; +import { GetAccountIdRpc } from "../engine/rpc/get-account-id"; import { newDefaultEvaluator } from "../rx"; -import { ApiOptions, NoPolicy } from "../types"; -import { clone$PerUserId, sharedByUserId } from "../util"; +import { NoPolicy } from "../types"; +import { observe$PerUserId, sharedByUserId } from "../util"; + +import { OptionsClassifier } from "./options-classifier"; const OPTIONS_FRAME_SIZE = 512; /** An email forwarding service configurable through an API. */ -export abstract class ForwarderGeneratorStrategy< - Options extends ApiOptions, +export class ForwarderGeneratorStrategy< + Settings extends ApiSettings, + Options extends Settings & IntegrationRequest = Settings & IntegrationRequest, > extends GeneratorStrategy<Options, NoPolicy> { /** Initializes the generator strategy * @param encryptService protects sensitive forwarder options @@ -34,26 +41,45 @@ export abstract class ForwarderGeneratorStrategy< * @param stateProvider creates the durable state for options storage */ constructor( + private readonly configuration: ForwarderConfiguration<Settings>, + private client: RestClient, + private i18nService: I18nService, private readonly encryptService: EncryptService, private readonly keyService: CryptoService, private stateProvider: StateProvider, - private readonly defaultOptions: Options, ) { super(); } - /** configures forwarder secret storage */ - protected abstract readonly key: UserKeyDefinition<Options>; - - /** configures forwarder import buffer */ - protected abstract readonly rolloverKey: BufferedKeyDefinition<Options, Options>; - // configuration readonly policy = PolicyType.PasswordGenerator; - defaults$ = clone$PerUserId(this.defaultOptions); + defaults$ = observe$PerUserId<Options>( + () => this.configuration.forwarder.defaultSettings as Options, + ); toEvaluator = newDefaultEvaluator<Options>(); durableState = sharedByUserId((userId) => this.getUserSecrets(userId)); + private get key() { + return this.configuration.forwarder.settings; + } + + private get rolloverKey() { + return this.configuration.forwarder.importBuffer; + } + + generate = async (options: Options) => { + const requestOptions: IntegrationRequest & AccountRequest = { website: options.website }; + + const getAccount = await this.getAccountId(this.configuration, options); + if (getAccount) { + requestOptions.accountId = await this.client.fetchJson(getAccount, requestOptions); + } + + const create = this.createForwardingAddress(this.configuration, options); + const result = await this.client.fetchJson(create, requestOptions); + return result; + }; + // per-user encrypted state private getUserSecrets(userId: UserId): SingleUserState<Options> { // construct the encryptor @@ -61,23 +87,27 @@ export abstract class ForwarderGeneratorStrategy< const encryptor = new UserKeyEncryptor(this.encryptService, this.keyService, packer); // always exclude request properties - const classifier = SecretClassifier.allSecret<Options>().exclude("website"); + const classifier = new OptionsClassifier<Settings, Options>(); // Derive the secret key definition - const key = SecretKeyDefinition.value(this.key.stateDefinition, this.key.key, classifier, { - deserializer: (d) => this.key.deserializer(d), - cleanupDelayMs: this.key.cleanupDelayMs, - clearOn: this.key.clearOn, - }); + const key = SecretKeyDefinition.value<Options, Record<string, never>, Settings>( + this.key.stateDefinition, + this.key.key, + classifier, + { + deserializer: (d: Jsonify<Options>) => this.key.deserializer(d as any) as any, + cleanupDelayMs: this.key.cleanupDelayMs, + clearOn: this.key.clearOn, + }, + ); // the type parameter is explicit because type inference fails for `Omit<Options, "website">` - const secretState = SecretState.from< - Options, - void, - Options, - Record<keyof Options, never>, - Omit<Options, "website"> - >(userId, key, this.stateProvider, encryptor); + const secretState = SecretState.from<Options, void, Options, Record<string, never>, Settings>( + userId, + key, + this.stateProvider, + encryptor, + ); // rollover should occur once the user key is available for decryption const canDecrypt$ = this.keyService @@ -90,6 +120,39 @@ export abstract class ForwarderGeneratorStrategy< canDecrypt$, ); - return rolloverState; + // cast through unknown required because there's no way to prove to + // the compiler that `OptionsClassifier` runs within the buffer wrapping + // the secret state. + return rolloverState as unknown as SingleUserState<Options>; + } + + private createContext<Settings>( + configuration: ForwarderConfiguration<Settings>, + settings: Settings, + ) { + return new ForwarderContext(configuration, settings, this.i18nService); + } + + private createForwardingAddress<Settings extends ApiSettings>( + configuration: ForwarderConfiguration<Settings>, + settings: Settings, + ) { + const context = this.createContext(configuration, settings); + const rpc = new CreateForwardingAddressRpc<Settings>(configuration, context); + return rpc; + } + + private getAccountId<Settings extends ApiSettings>( + configuration: ForwarderConfiguration<Settings>, + settings: Settings, + ) { + if (!configuration.forwarder.getAccountId) { + return null; + } + + const context = this.createContext(configuration, settings); + const rpc = new GetAccountIdRpc<Settings>(configuration, context); + + return rpc; } } diff --git a/libs/tools/generator/core/src/strategies/forwarders/addy-io.spec.ts b/libs/tools/generator/core/src/strategies/forwarders/addy-io.spec.ts deleted file mode 100644 index 438ae4bffd2..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/addy-io.spec.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { firstValueFrom } from "rxjs"; - -import { UserId } from "@bitwarden/common/types/guid"; - -import { Forwarders, DefaultAddyIoOptions } from "../../data"; -import { ADDY_IO_FORWARDER } from "../storage"; - -import { AddyIoForwarder } from "./addy-io"; -import { mockApiService, mockI18nService } from "./mocks.jest"; - -const SomeUser = "some user" as UserId; - -describe("Addy.io Forwarder", () => { - it("key returns the Addy IO forwarder key", () => { - const forwarder = new AddyIoForwarder(null, null, null, null, null); - - expect(forwarder.key).toBe(ADDY_IO_FORWARDER); - }); - - describe("defaults$", () => { - it("should return the default subaddress options", async () => { - const strategy = new AddyIoForwarder(null, null, null, null, null); - - const result = await firstValueFrom(strategy.defaults$(SomeUser)); - - expect(result).toEqual(DefaultAddyIoOptions); - }); - }); - - describe("generate(string | null, SelfHostedApiOptions & EmailDomainOptions)", () => { - it.each([null, ""])("throws an error if the token is missing (token = %p)", async (token) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token, - domain: "example.com", - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith("forwaderInvalidToken", Forwarders.AddyIo.name); - }); - - it.each([null, ""])( - "throws an error if the domain is missing (domain = %p)", - async (domain) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain, - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwarderNoDomain"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith("forwarderNoDomain", Forwarders.AddyIo.name); - }, - ); - - it.each([null, ""])( - "throws an error if the baseUrl is missing (baseUrl = %p)", - async (baseUrl) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - baseUrl, - }), - ).rejects.toEqual("forwarderNoUrl"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith("forwarderNoUrl", Forwarders.AddyIo.name); - }, - ); - - it.each([ - ["forwarderGeneratedByWithWebsite", "provided", "bitwarden.com", "bitwarden.com"], - ["forwarderGeneratedByWithWebsite", "provided", "httpbin.org", "httpbin.org"], - ["forwarderGeneratedBy", "not provided", null, ""], - ["forwarderGeneratedBy", "not provided", "", ""], - ])( - "describes the website with %p when the website is %s (= %p)", - async (translationKey, _ignored, website, expectedWebsite) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - await forwarder.generate({ - website, - token: "token", - domain: "example.com", - baseUrl: "https://api.example.com", - }); - - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith(translationKey, expectedWebsite); - }, - ); - - it.each([ - ["jane.doe@example.com", 201], - ["john.doe@example.com", 201], - ["jane.doe@example.com", 200], - ["john.doe@example.com", 200], - ])( - "returns the generated email address (= %p) if the request is successful (status = %p)", - async (email, status) => { - const apiService = mockApiService(status, { data: { email } }); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - const result = await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - baseUrl: "https://api.example.com", - }); - - expect(result).toEqual(email); - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - }, - ); - - it("throws an invalid token error if the request fails with a 401", async () => { - const apiService = mockApiService(401, {}); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwaderInvalidToken", - Forwarders.AddyIo.name, - ); - }); - - it("throws an unknown error if the request fails and no status is provided", async () => { - const apiService = mockApiService(500, {}); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderUnknownError", - Forwarders.AddyIo.name, - ); - }); - - it.each([ - [100, "Continue"], - [202, "Accepted"], - [300, "Multiple Choices"], - [418, "I'm a teapot"], - [500, "Internal Server Error"], - [600, "Unknown Status"], - ])( - "throws an error with the status text if the request returns any other status code (= %i) and a status (= %p) is provided", - async (statusCode, statusText) => { - const apiService = mockApiService(statusCode, {}, statusText); - const i18nService = mockI18nService(); - - const forwarder = new AddyIoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwarderError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderError", - Forwarders.AddyIo.name, - statusText, - ); - }, - ); - }); -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/addy-io.ts b/libs/tools/generator/core/src/strategies/forwarders/addy-io.ts deleted file mode 100644 index 33ffb626d4f..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/addy-io.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { StateProvider } from "@bitwarden/common/platform/state"; - -import { DefaultAddyIoOptions, Forwarders } from "../../data"; -import { EmailDomainOptions, SelfHostedApiOptions } from "../../types"; -import { ForwarderGeneratorStrategy } from "../forwarder-generator-strategy"; -import { ADDY_IO_FORWARDER, ADDY_IO_BUFFER } from "../storage"; - -/** Generates a forwarding address for addy.io (formerly anon addy) */ -export class AddyIoForwarder extends ForwarderGeneratorStrategy< - SelfHostedApiOptions & EmailDomainOptions -> { - /** Instantiates the forwarder - * @param apiService used for ajax requests to the forwarding service - * @param i18nService used to look up error strings - * @param encryptService protects sensitive forwarder options - * @param keyService looks up the user key when protecting data. - * @param stateProvider creates the durable state for options storage - */ - constructor( - private apiService: ApiService, - private i18nService: I18nService, - encryptService: EncryptService, - keyService: CryptoService, - stateProvider: StateProvider, - ) { - super(encryptService, keyService, stateProvider, DefaultAddyIoOptions); - } - - // configuration - readonly key = ADDY_IO_FORWARDER; - readonly rolloverKey = ADDY_IO_BUFFER; - - // request - generate = async (options: SelfHostedApiOptions & EmailDomainOptions) => { - if (!options.token || options.token === "") { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.AddyIo.name); - throw error; - } - if (!options.domain || options.domain === "") { - const error = this.i18nService.t("forwarderNoDomain", Forwarders.AddyIo.name); - throw error; - } - if (!options.baseUrl || options.baseUrl === "") { - const error = this.i18nService.t("forwarderNoUrl", Forwarders.AddyIo.name); - throw error; - } - - let descriptionId = "forwarderGeneratedByWithWebsite"; - if (!options.website || options.website === "") { - descriptionId = "forwarderGeneratedBy"; - } - const description = this.i18nService.t(descriptionId, options.website ?? ""); - - const url = options.baseUrl + "/api/v1/aliases"; - const request = new Request(url, { - redirect: "manual", - cache: "no-store", - method: "POST", - headers: new Headers({ - Authorization: "Bearer " + options.token, - "Content-Type": "application/json", - "X-Requested-With": "XMLHttpRequest", - }), - body: JSON.stringify({ - domain: options.domain, - description, - }), - }); - - const response = await this.apiService.nativeFetch(request); - if (response.status === 200 || response.status === 201) { - const json = await response.json(); - return json?.data?.email; - } else if (response.status === 401) { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.AddyIo.name); - throw error; - } else if (response?.statusText) { - const error = this.i18nService.t( - "forwarderError", - Forwarders.AddyIo.name, - response.statusText, - ); - throw error; - } else { - const error = this.i18nService.t("forwarderUnknownError", Forwarders.AddyIo.name); - throw error; - } - }; -} - -export const DefaultOptions = Object.freeze({ - website: null, - baseUrl: "https://app.addy.io", - domain: "", - token: "", -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.spec.ts b/libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.spec.ts deleted file mode 100644 index 4c4566e6ecc..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.spec.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { firstValueFrom } from "rxjs"; - -import { UserId } from "@bitwarden/common/types/guid"; - -import { Forwarders, DefaultDuckDuckGoOptions } from "../../data"; -import { DUCK_DUCK_GO_FORWARDER } from "../storage"; - -import { DuckDuckGoForwarder } from "./duck-duck-go"; -import { mockApiService, mockI18nService } from "./mocks.jest"; - -const SomeUser = "some user" as UserId; - -describe("DuckDuckGo Forwarder", () => { - it("key returns the Duck Duck Go forwarder key", () => { - const forwarder = new DuckDuckGoForwarder(null, null, null, null, null); - - expect(forwarder.key).toBe(DUCK_DUCK_GO_FORWARDER); - }); - - describe("defaults$", () => { - it("should return the default subaddress options", async () => { - const strategy = new DuckDuckGoForwarder(null, null, null, null, null); - - const result = await firstValueFrom(strategy.defaults$(SomeUser)); - - expect(result).toEqual(DefaultDuckDuckGoOptions); - }); - }); - - describe("generate(string | null, SelfHostedApiOptions & EmailDomainOptions)", () => { - it.each([null, ""])("throws an error if the token is missing (token = %p)", async (token) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new DuckDuckGoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token, - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith( - "forwaderInvalidToken", - Forwarders.DuckDuckGo.name, - ); - }); - - it.each([ - ["jane.doe@duck.com", 201, "jane.doe"], - ["john.doe@duck.com", 201, "john.doe"], - ["jane.doe@duck.com", 200, "jane.doe"], - ["john.doe@duck.com", 200, "john.doe"], - ])( - "returns the generated email address (= %p) if the request is successful (status = %p)", - async (email, status, address) => { - const apiService = mockApiService(status, { address }); - const i18nService = mockI18nService(); - - const forwarder = new DuckDuckGoForwarder(apiService, i18nService, null, null, null); - - const result = await forwarder.generate({ - website: null, - token: "token", - }); - - expect(result).toEqual(email); - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - }, - ); - - it("throws an invalid token error if the request fails with a 401", async () => { - const apiService = mockApiService(401, {}); - const i18nService = mockI18nService(); - - const forwarder = new DuckDuckGoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwaderInvalidToken", - Forwarders.DuckDuckGo.name, - ); - }); - - it("throws an unknown error if the request is successful but an address isn't present", async () => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new DuckDuckGoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwarderUnknownError", - Forwarders.DuckDuckGo.name, - ); - }); - - it.each([100, 202, 300, 418, 500, 600])( - "throws an unknown error if the request returns any other status code (= %i)", - async (statusCode) => { - const apiService = mockApiService(statusCode, {}); - const i18nService = mockI18nService(); - - const forwarder = new DuckDuckGoForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwarderUnknownError", - Forwarders.DuckDuckGo.name, - ); - }, - ); - }); -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.ts b/libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.ts deleted file mode 100644 index cf1b26508c5..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/duck-duck-go.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { StateProvider } from "@bitwarden/common/platform/state"; - -import { Forwarders, DefaultDuckDuckGoOptions } from "../../data"; -import { ApiOptions } from "../../types"; -import { ForwarderGeneratorStrategy } from "../forwarder-generator-strategy"; -import { DUCK_DUCK_GO_FORWARDER, DUCK_DUCK_GO_BUFFER } from "../storage"; - -/** Generates a forwarding address for DuckDuckGo */ -export class DuckDuckGoForwarder extends ForwarderGeneratorStrategy<ApiOptions> { - /** Instantiates the forwarder - * @param apiService used for ajax requests to the forwarding service - * @param i18nService used to look up error strings - * @param encryptService protects sensitive forwarder options - * @param keyService looks up the user key when protecting data. - * @param stateProvider creates the durable state for options storage - */ - constructor( - private apiService: ApiService, - private i18nService: I18nService, - encryptService: EncryptService, - keyService: CryptoService, - stateProvider: StateProvider, - ) { - super(encryptService, keyService, stateProvider, DefaultDuckDuckGoOptions); - } - - // configuration - readonly key = DUCK_DUCK_GO_FORWARDER; - readonly rolloverKey = DUCK_DUCK_GO_BUFFER; - - // request - generate = async (options: ApiOptions): Promise<string> => { - if (!options.token || options.token === "") { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.DuckDuckGo.name); - throw error; - } - - const url = "https://quack.duckduckgo.com/api/email/addresses"; - const request = new Request(url, { - redirect: "manual", - cache: "no-store", - method: "POST", - headers: new Headers({ - Authorization: "Bearer " + options.token, - "Content-Type": "application/json", - }), - }); - - const response = await this.apiService.nativeFetch(request); - if (response.status === 200 || response.status === 201) { - const json = await response.json(); - if (json.address) { - return `${json.address}@duck.com`; - } else { - const error = this.i18nService.t("forwarderUnknownError", Forwarders.DuckDuckGo.name); - throw error; - } - } else if (response.status === 401) { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.DuckDuckGo.name); - throw error; - } else { - const error = this.i18nService.t("forwarderUnknownError", Forwarders.DuckDuckGo.name); - throw error; - } - }; -} - -export const DefaultOptions = Object.freeze({ - website: null, - token: "", -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/fastmail.spec.ts b/libs/tools/generator/core/src/strategies/forwarders/fastmail.spec.ts deleted file mode 100644 index 6920f69647f..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/fastmail.spec.ts +++ /dev/null @@ -1,281 +0,0 @@ -import { firstValueFrom } from "rxjs"; - -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserId } from "@bitwarden/common/types/guid"; - -import { Forwarders, DefaultFastmailOptions } from "../../data"; -import { FASTMAIL_FORWARDER } from "../storage"; - -import { FastmailForwarder } from "./fastmail"; -import { mockI18nService } from "./mocks.jest"; - -const SomeUser = "some user" as UserId; - -type MockResponse = { status: number; body: any }; - -// fastmail calls nativeFetch first to resolve the accountId, -// then it calls nativeFetch again to create the forwarding address. -// The common mock doesn't work here, because this test needs to return multiple responses -function mockApiService(accountId: MockResponse, forwardingAddress: MockResponse) { - function response(r: MockResponse) { - return { - status: r.status, - json: jest.fn().mockImplementation(() => Promise.resolve(r.body)), - }; - } - - return { - nativeFetch: jest - .fn() - .mockImplementationOnce((r: Request) => response(accountId)) - .mockImplementationOnce((r: Request) => response(forwardingAddress)), - } as unknown as ApiService; -} - -const EmptyResponse: MockResponse = Object.freeze({ - status: 200, - body: Object.freeze({}), -}); - -const AccountIdSuccess: MockResponse = Object.freeze({ - status: 200, - body: Object.freeze({ - primaryAccounts: Object.freeze({ - "https://www.fastmail.com/dev/maskedemail": "accountId", - }), - }), -}); - -// the tests -describe("Fastmail Forwarder", () => { - it("key returns the Fastmail forwarder key", () => { - const forwarder = new FastmailForwarder(null, null, null, null, null); - - expect(forwarder.key).toBe(FASTMAIL_FORWARDER); - }); - - describe("defaults$", () => { - it("should return the default subaddress options", async () => { - const strategy = new FastmailForwarder(null, null, null, null, null); - - const result = await firstValueFrom(strategy.defaults$(SomeUser)); - - expect(result).toEqual(DefaultFastmailOptions); - }); - }); - - describe("generate(string | null, SelfHostedApiOptions & EmailDomainOptions)", () => { - it.each([null, ""])("throws an error if the token is missing (token = %p)", async (token) => { - const apiService = mockApiService(AccountIdSuccess, EmptyResponse); - const i18nService = mockI18nService(); - - const forwarder = new FastmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token, - domain: "example.com", - prefix: "prefix", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith("forwaderInvalidToken", Forwarders.Fastmail.name); - }); - - it.each([401, 403])( - "throws a no account id error if the accountId request responds with a status other than 200", - async (status) => { - const apiService = mockApiService({ status, body: {} }, EmptyResponse); - const i18nService = mockI18nService(); - - const forwarder = new FastmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - prefix: "prefix", - }), - ).rejects.toEqual("forwarderNoAccountId"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwarderNoAccountId", - Forwarders.Fastmail.name, - ); - }, - ); - - it.each([ - ["jane.doe@example.com", 200], - ["john.doe@example.com", 200], - ])( - "returns the generated email address (= %p) if both requests are successful (status = %p)", - async (email, status) => { - const apiService = mockApiService(AccountIdSuccess, { - status, - body: { - methodResponses: [["MaskedEmail/set", { created: { "new-masked-email": { email } } }]], - }, - }); - const i18nService = mockI18nService(); - - const forwarder = new FastmailForwarder(apiService, i18nService, null, null, null); - - const result = await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - prefix: "prefix", - }); - - expect(result).toEqual(email); - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - }, - ); - - it.each([ - [ - "It turned inside out!", - [ - "MaskedEmail/set", - { notCreated: { "new-masked-email": { description: "It turned inside out!" } } }, - ], - ], - ["And then it exploded!", ["error", { description: "And then it exploded!" }]], - ])( - "throws a forwarder error (= %p) if both requests are successful (status = %p) but masked email creation fails", - async (description, response) => { - const apiService = mockApiService(AccountIdSuccess, { - status: 200, - body: { - methodResponses: [response], - }, - }); - const i18nService = mockI18nService(); - - const forwarder = new FastmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - prefix: "prefix", - }), - ).rejects.toEqual("forwarderError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwarderError", - Forwarders.Fastmail.name, - description, - ); - }, - ); - - it.each([401, 403])( - "throws an invalid token error if the jmap request fails with a %i", - async (status) => { - const apiService = mockApiService(AccountIdSuccess, { status, body: {} }); - const i18nService = mockI18nService(); - - const forwarder = new FastmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - prefix: "prefix", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwaderInvalidToken", - Forwarders.Fastmail.name, - ); - }, - ); - - it.each([ - null, - [], - [[]], - [["MaskedEmail/not-a-real-op"]], - [["MaskedEmail/set", null]], - [["MaskedEmail/set", { created: null }]], - [["MaskedEmail/set", { created: { "new-masked-email": null } }]], - [["MaskedEmail/set", { notCreated: null }]], - [["MaskedEmail/set", { notCreated: { "new-masked-email": null } }]], - ])( - "throws an unknown error if the jmap request is malformed (= %p)", - async (responses: any) => { - const apiService = mockApiService(AccountIdSuccess, { - status: 200, - body: { - methodResponses: responses, - }, - }); - const i18nService = mockI18nService(); - - const forwarder = new FastmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - prefix: "prefix", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwarderUnknownError", - Forwarders.Fastmail.name, - ); - }, - ); - - it.each([100, 202, 300, 418, 500, 600])( - "throws an unknown error if the request returns any other status code (= %i)", - async (statusCode) => { - const apiService = mockApiService(AccountIdSuccess, { status: statusCode, body: {} }); - const i18nService = mockI18nService(); - - const forwarder = new FastmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - prefix: "prefix", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith( - "forwarderUnknownError", - Forwarders.Fastmail.name, - ); - }, - ); - }); -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/fastmail.ts b/libs/tools/generator/core/src/strategies/forwarders/fastmail.ts deleted file mode 100644 index 283abc3e886..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/fastmail.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { StateProvider } from "@bitwarden/common/platform/state"; - -import { Forwarders, DefaultFastmailOptions } from "../../data"; -import { EmailPrefixOptions, ApiOptions } from "../../types"; -import { ForwarderGeneratorStrategy } from "../forwarder-generator-strategy"; -import { FASTMAIL_FORWARDER, FASTMAIL_BUFFER } from "../storage"; - -/** Generates a forwarding address for Fastmail */ -export class FastmailForwarder extends ForwarderGeneratorStrategy<ApiOptions & EmailPrefixOptions> { - /** Instantiates the forwarder - * @param apiService used for ajax requests to the forwarding service - * @param i18nService used to look up error strings - * @param encryptService protects sensitive forwarder options - * @param keyService looks up the user key when protecting data. - * @param stateProvider creates the durable state for options storage - */ - constructor( - private apiService: ApiService, - private i18nService: I18nService, - encryptService: EncryptService, - keyService: CryptoService, - stateProvider: StateProvider, - ) { - super(encryptService, keyService, stateProvider, DefaultFastmailOptions); - } - - // configuration - readonly key = FASTMAIL_FORWARDER; - readonly rolloverKey = FASTMAIL_BUFFER; - - // request - generate = async (options: ApiOptions & EmailPrefixOptions) => { - if (!options.token || options.token === "") { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.Fastmail.name); - throw error; - } - - const accountId = await this.getAccountId(options); - if (!accountId || accountId === "") { - const error = this.i18nService.t("forwarderNoAccountId", Forwarders.Fastmail.name); - throw error; - } - - const body = JSON.stringify({ - using: ["https://www.fastmail.com/dev/maskedemail", "urn:ietf:params:jmap:core"], - methodCalls: [ - [ - "MaskedEmail/set", - { - accountId: accountId, - create: { - "new-masked-email": { - state: "enabled", - description: "", - forDomain: options.website ?? "", - emailPrefix: options.prefix, - }, - }, - }, - "0", - ], - ], - }); - - const requestInit: RequestInit = { - redirect: "manual", - cache: "no-store", - method: "POST", - headers: new Headers({ - Authorization: "Bearer " + options.token, - "Content-Type": "application/json", - }), - body, - }; - - const url = "https://api.fastmail.com/jmap/api/"; - const request = new Request(url, requestInit); - - const response = await this.apiService.nativeFetch(request); - if (response.status === 200) { - const json = await response.json(); - if ( - json.methodResponses != null && - json.methodResponses.length > 0 && - json.methodResponses[0].length > 0 - ) { - if (json.methodResponses[0][0] === "MaskedEmail/set") { - if (json.methodResponses[0][1]?.created?.["new-masked-email"] != null) { - return json.methodResponses[0][1]?.created?.["new-masked-email"]?.email; - } - if (json.methodResponses[0][1]?.notCreated?.["new-masked-email"] != null) { - const errorDescription = - json.methodResponses[0][1]?.notCreated?.["new-masked-email"]?.description; - const error = this.i18nService.t( - "forwarderError", - Forwarders.Fastmail.name, - errorDescription, - ); - throw error; - } - } else if (json.methodResponses[0][0] === "error") { - const errorDescription = json.methodResponses[0][1]?.description; - const error = this.i18nService.t( - "forwarderError", - Forwarders.Fastmail.name, - errorDescription, - ); - throw error; - } - } - } else if (response.status === 401 || response.status === 403) { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.Fastmail.name); - throw error; - } - - const error = this.i18nService.t("forwarderUnknownError", Forwarders.Fastmail.name); - throw error; - }; - - private async getAccountId(options: ApiOptions): Promise<string> { - const requestInit: RequestInit = { - cache: "no-store", - method: "GET", - headers: new Headers({ - Authorization: "Bearer " + options.token, - }), - }; - const url = "https://api.fastmail.com/.well-known/jmap"; - const request = new Request(url, requestInit); - const response = await this.apiService.nativeFetch(request); - if (response.status === 200) { - const json = await response.json(); - if (json.primaryAccounts != null) { - return json.primaryAccounts["https://www.fastmail.com/dev/maskedemail"]; - } - } - return null; - } -} - -export const DefaultOptions = Object.freeze({ - website: null, - domain: "", - prefix: "", - token: "", -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/firefox-relay.spec.ts b/libs/tools/generator/core/src/strategies/forwarders/firefox-relay.spec.ts deleted file mode 100644 index 603694bdd85..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/firefox-relay.spec.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { firstValueFrom } from "rxjs"; - -import { UserId } from "@bitwarden/common/types/guid"; - -import { Forwarders, DefaultFirefoxRelayOptions } from "../../data"; -import { FIREFOX_RELAY_FORWARDER } from "../storage"; - -import { FirefoxRelayForwarder } from "./firefox-relay"; -import { mockApiService, mockI18nService } from "./mocks.jest"; - -const SomeUser = "some user" as UserId; - -describe("Firefox Relay Forwarder", () => { - it("key returns the Firefox Relay forwarder key", () => { - const forwarder = new FirefoxRelayForwarder(null, null, null, null, null); - - expect(forwarder.key).toBe(FIREFOX_RELAY_FORWARDER); - }); - - describe("defaults$", () => { - it("should return the default subaddress options", async () => { - const strategy = new FirefoxRelayForwarder(null, null, null, null, null); - - const result = await firstValueFrom(strategy.defaults$(SomeUser)); - - expect(result).toEqual(DefaultFirefoxRelayOptions); - }); - }); - - describe("generate(string | null, SelfHostedApiOptions & EmailDomainOptions)", () => { - it.each([null, ""])("throws an error if the token is missing (token = %p)", async (token) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new FirefoxRelayForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token, - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith( - "forwaderInvalidToken", - Forwarders.FirefoxRelay.name, - ); - }); - - it.each([ - ["forwarderGeneratedByWithWebsite", "provided", "bitwarden.com", "bitwarden.com"], - ["forwarderGeneratedByWithWebsite", "provided", "httpbin.org", "httpbin.org"], - ["forwarderGeneratedBy", "not provided", null, ""], - ["forwarderGeneratedBy", "not provided", "", ""], - ])( - "describes the website with %p when the website is %s (= %p)", - async (translationKey, _ignored, website, expectedWebsite) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new FirefoxRelayForwarder(apiService, i18nService, null, null, null); - - await forwarder.generate({ - website, - token: "token", - }); - - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith(translationKey, expectedWebsite); - }, - ); - - it.each([ - ["jane.doe@duck.com", 201], - ["john.doe@duck.com", 201], - ["jane.doe@duck.com", 200], - ["john.doe@duck.com", 200], - ])( - "returns the generated email address (= %p) if the request is successful (status = %p)", - async (full_address, status) => { - const apiService = mockApiService(status, { full_address }); - const i18nService = mockI18nService(); - - const forwarder = new FirefoxRelayForwarder(apiService, i18nService, null, null, null); - - const result = await forwarder.generate({ - website: null, - token: "token", - }); - - expect(result).toEqual(full_address); - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - }, - ); - - it("throws an invalid token error if the request fails with a 401", async () => { - const apiService = mockApiService(401, {}); - const i18nService = mockI18nService(); - - const forwarder = new FirefoxRelayForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwaderInvalidToken", - Forwarders.FirefoxRelay.name, - ); - }); - - it.each([100, 202, 300, 418, 500, 600])( - "throws an unknown error if the request returns any other status code (= %i)", - async (statusCode) => { - const apiService = mockApiService(statusCode, {}); - const i18nService = mockI18nService(); - - const forwarder = new FirefoxRelayForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderUnknownError", - Forwarders.FirefoxRelay.name, - ); - }, - ); - }); -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/firefox-relay.ts b/libs/tools/generator/core/src/strategies/forwarders/firefox-relay.ts deleted file mode 100644 index b7e7ea87858..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/firefox-relay.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { StateProvider } from "@bitwarden/common/platform/state"; - -import { Forwarders, DefaultFirefoxRelayOptions } from "../../data"; -import { ApiOptions } from "../../types"; -import { ForwarderGeneratorStrategy } from "../forwarder-generator-strategy"; -import { FIREFOX_RELAY_FORWARDER, FIREFOX_RELAY_BUFFER } from "../storage"; - -/** Generates a forwarding address for Firefox Relay */ -export class FirefoxRelayForwarder extends ForwarderGeneratorStrategy<ApiOptions> { - /** Instantiates the forwarder - * @param apiService used for ajax requests to the forwarding service - * @param i18nService used to look up error strings - * @param encryptService protects sensitive forwarder options - * @param keyService looks up the user key when protecting data. - * @param stateProvider creates the durable state for options storage - */ - constructor( - private apiService: ApiService, - private i18nService: I18nService, - encryptService: EncryptService, - keyService: CryptoService, - stateProvider: StateProvider, - ) { - super(encryptService, keyService, stateProvider, DefaultFirefoxRelayOptions); - } - - // configuration - readonly key = FIREFOX_RELAY_FORWARDER; - readonly rolloverKey = FIREFOX_RELAY_BUFFER; - - // request - generate = async (options: ApiOptions) => { - if (!options.token || options.token === "") { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.FirefoxRelay.name); - throw error; - } - - const url = "https://relay.firefox.com/api/v1/relayaddresses/"; - - let descriptionId = "forwarderGeneratedByWithWebsite"; - if (!options.website || options.website === "") { - descriptionId = "forwarderGeneratedBy"; - } - const description = this.i18nService.t(descriptionId, options.website ?? ""); - - const request = new Request(url, { - redirect: "manual", - cache: "no-store", - method: "POST", - headers: new Headers({ - Authorization: "Token " + options.token, - "Content-Type": "application/json", - }), - body: JSON.stringify({ - enabled: true, - generated_for: options.website, - description, - }), - }); - - const response = await this.apiService.nativeFetch(request); - if (response.status === 401) { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.FirefoxRelay.name); - throw error; - } else if (response.status === 200 || response.status === 201) { - const json = await response.json(); - return json.full_address; - } else { - const error = this.i18nService.t("forwarderUnknownError", Forwarders.FirefoxRelay.name); - throw error; - } - }; -} - -export const DefaultOptions = Object.freeze({ - website: null, - token: "", -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/forward-email.spec.ts b/libs/tools/generator/core/src/strategies/forwarders/forward-email.spec.ts deleted file mode 100644 index d5d6ba3d335..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/forward-email.spec.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { firstValueFrom } from "rxjs"; - -import { UserId } from "@bitwarden/common/types/guid"; - -import { Forwarders, DefaultForwardEmailOptions } from "../../data"; -import { FORWARD_EMAIL_FORWARDER } from "../storage"; - -import { ForwardEmailForwarder } from "./forward-email"; -import { mockApiService, mockI18nService } from "./mocks.jest"; - -const SomeUser = "some user" as UserId; - -describe("ForwardEmail Forwarder", () => { - it("key returns the Forward Email forwarder key", () => { - const forwarder = new ForwardEmailForwarder(null, null, null, null, null); - - expect(forwarder.key).toBe(FORWARD_EMAIL_FORWARDER); - }); - - describe("defaults$", () => { - it("should return the default subaddress options", async () => { - const strategy = new ForwardEmailForwarder(null, null, null, null, null); - - const result = await firstValueFrom(strategy.defaults$(SomeUser)); - - expect(result).toEqual(DefaultForwardEmailOptions); - }); - }); - - describe("generate(string | null, SelfHostedApiOptions & EmailDomainOptions)", () => { - it.each([null, ""])("throws an error if the token is missing (token = %p)", async (token) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token, - domain: "example.com", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith( - "forwaderInvalidToken", - Forwarders.ForwardEmail.name, - ); - }); - - it.each([null, ""])( - "throws an error if the domain is missing (domain = %p)", - async (domain) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain, - }), - ).rejects.toEqual("forwarderNoDomain"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith( - "forwarderNoDomain", - Forwarders.ForwardEmail.name, - ); - }, - ); - - it.each([ - ["forwarderGeneratedByWithWebsite", "provided", "bitwarden.com", "bitwarden.com"], - ["forwarderGeneratedByWithWebsite", "provided", "httpbin.org", "httpbin.org"], - ["forwarderGeneratedBy", "not provided", null, ""], - ["forwarderGeneratedBy", "not provided", "", ""], - ])( - "describes the website with %p when the website is %s (= %p)", - async (translationKey, _ignored, website, expectedWebsite) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await forwarder.generate({ - website, - token: "token", - domain: "example.com", - }); - - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith(translationKey, expectedWebsite); - }, - ); - - it.each([ - ["jane.doe@example.com", 201, { name: "jane.doe", domain: { name: "example.com" } }], - ["jane.doe@example.com", 201, { name: "jane.doe" }], - ["john.doe@example.com", 201, { name: "john.doe", domain: { name: "example.com" } }], - ["john.doe@example.com", 201, { name: "john.doe" }], - ["jane.doe@example.com", 200, { name: "jane.doe", domain: { name: "example.com" } }], - ["jane.doe@example.com", 200, { name: "jane.doe" }], - ["john.doe@example.com", 200, { name: "john.doe", domain: { name: "example.com" } }], - ["john.doe@example.com", 200, { name: "john.doe" }], - ])( - "returns the generated email address (= %p) if the request is successful (status = %p)", - async (email, status, response) => { - const apiService = mockApiService(status, response); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - const result = await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - }); - - expect(result).toEqual(email); - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - }, - ); - - it("throws an invalid token error if the request fails with a 401", async () => { - const apiService = mockApiService(401, {}); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwaderInvalidToken", - Forwarders.ForwardEmail.name, - undefined, - ); - }); - - it("throws an invalid token error with a message if the request fails with a 401 and message", async () => { - const apiService = mockApiService(401, { message: "A message" }); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - }), - ).rejects.toEqual("forwaderInvalidTokenWithMessage"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwaderInvalidTokenWithMessage", - Forwarders.ForwardEmail.name, - "A message", - ); - }); - - it.each([{}, null])( - "throws an unknown error if the request fails and no status (= %p) is provided", - async (json) => { - const apiService = mockApiService(500, json); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderUnknownError", - Forwarders.ForwardEmail.name, - ); - }, - ); - - it.each([ - [100, "Continue"], - [202, "Accepted"], - [300, "Multiple Choices"], - [418, "I'm a teapot"], - [500, "Internal Server Error"], - [600, "Unknown Status"], - ])( - "throws an error with the status text if the request returns any other status code (= %i) and a status (= %p) is provided", - async (statusCode, message) => { - const apiService = mockApiService(statusCode, { message }); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - }), - ).rejects.toEqual("forwarderError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderError", - Forwarders.ForwardEmail.name, - message, - ); - }, - ); - - it.each([ - [100, "Continue"], - [202, "Accepted"], - [300, "Multiple Choices"], - [418, "I'm a teapot"], - [500, "Internal Server Error"], - [600, "Unknown Status"], - ])( - "throws an error with the status text if the request returns any other status code (= %i) and a status (= %p) is provided", - async (statusCode, error) => { - const apiService = mockApiService(statusCode, { error }); - const i18nService = mockI18nService(); - - const forwarder = new ForwardEmailForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - domain: "example.com", - }), - ).rejects.toEqual("forwarderError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderError", - Forwarders.ForwardEmail.name, - error, - ); - }, - ); - }); -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/forward-email.ts b/libs/tools/generator/core/src/strategies/forwarders/forward-email.ts deleted file mode 100644 index 90ea0eb52c4..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/forward-email.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { StateProvider } from "@bitwarden/common/platform/state"; - -import { Forwarders, DefaultForwardEmailOptions } from "../../data"; -import { EmailDomainOptions, ApiOptions } from "../../types"; -import { ForwarderGeneratorStrategy } from "../forwarder-generator-strategy"; -import { FORWARD_EMAIL_FORWARDER, FORWARD_EMAIL_BUFFER } from "../storage"; - -/** Generates a forwarding address for Forward Email */ -export class ForwardEmailForwarder extends ForwarderGeneratorStrategy< - ApiOptions & EmailDomainOptions -> { - /** Instantiates the forwarder - * @param apiService used for ajax requests to the forwarding service - * @param i18nService used to look up error strings - * @param encryptService protects sensitive forwarder options - * @param keyService looks up the user key when protecting data. - * @param stateProvider creates the durable state for options storage - */ - constructor( - private apiService: ApiService, - private i18nService: I18nService, - encryptService: EncryptService, - keyService: CryptoService, - stateProvider: StateProvider, - ) { - super(encryptService, keyService, stateProvider, DefaultForwardEmailOptions); - } - - // configuration - readonly key = FORWARD_EMAIL_FORWARDER; - readonly rolloverKey = FORWARD_EMAIL_BUFFER; - - // request - generate = async (options: ApiOptions & EmailDomainOptions) => { - if (!options.token || options.token === "") { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.ForwardEmail.name); - throw error; - } - if (!options.domain || options.domain === "") { - const error = this.i18nService.t("forwarderNoDomain", Forwarders.ForwardEmail.name); - throw error; - } - - const url = `https://api.forwardemail.net/v1/domains/${options.domain}/aliases`; - - let descriptionId = "forwarderGeneratedByWithWebsite"; - if (!options.website || options.website === "") { - descriptionId = "forwarderGeneratedBy"; - } - const description = this.i18nService.t(descriptionId, options.website ?? ""); - - const request = new Request(url, { - redirect: "manual", - cache: "no-store", - method: "POST", - headers: new Headers({ - Authorization: "Basic " + Utils.fromUtf8ToB64(options.token + ":"), - "Content-Type": "application/json", - }), - body: JSON.stringify({ - labels: options.website, - description, - }), - }); - - const response = await this.apiService.nativeFetch(request); - const json = await response.json(); - - if (response.status === 401) { - const messageKey = - "message" in json ? "forwaderInvalidTokenWithMessage" : "forwaderInvalidToken"; - const error = this.i18nService.t(messageKey, Forwarders.ForwardEmail.name, json.message); - throw error; - } else if (response.status === 200 || response.status === 201) { - const { name, domain } = await response.json(); - const domainPart = domain?.name || options.domain; - return `${name}@${domainPart}`; - } else if (json?.message) { - const error = this.i18nService.t( - "forwarderError", - Forwarders.ForwardEmail.name, - json.message, - ); - throw error; - } else if (json?.error) { - const error = this.i18nService.t("forwarderError", Forwarders.ForwardEmail.name, json.error); - throw error; - } else { - const error = this.i18nService.t("forwarderUnknownError", Forwarders.ForwardEmail.name); - throw error; - } - }; -} - -export const DefaultOptions = Object.freeze({ - website: null, - token: "", - domain: "", -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/mocks.jest.ts b/libs/tools/generator/core/src/strategies/forwarders/mocks.jest.ts deleted file mode 100644 index fa1f8ae095e..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/mocks.jest.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; - -/** a mock {@link ApiService} that returns a fetch-like response with a given status and body */ -export function mockApiService(status: number, body: any, statusText?: string) { - return { - nativeFetch: jest.fn().mockImplementation((r: Request) => { - return { - status, - statusText, - json: jest.fn().mockImplementation(() => Promise.resolve(body)), - }; - }), - } as unknown as ApiService; -} - -/** a mock {@link I18nService} that returns the translation key */ -export function mockI18nService() { - return { - t: jest.fn().mockImplementation((key: string) => key), - } as unknown as I18nService; -} diff --git a/libs/tools/generator/core/src/strategies/forwarders/simple-login.spec.ts b/libs/tools/generator/core/src/strategies/forwarders/simple-login.spec.ts deleted file mode 100644 index de10fd9e864..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/simple-login.spec.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { firstValueFrom } from "rxjs"; - -import { UserId } from "@bitwarden/common/types/guid"; - -import { Forwarders, DefaultSimpleLoginOptions } from "../../data"; -import { SIMPLE_LOGIN_FORWARDER } from "../storage"; - -import { mockApiService, mockI18nService } from "./mocks.jest"; -import { SimpleLoginForwarder } from "./simple-login"; - -const SomeUser = "some user" as UserId; - -describe("SimpleLogin Forwarder", () => { - it("key returns the Simple Login forwarder key", () => { - const forwarder = new SimpleLoginForwarder(null, null, null, null, null); - - expect(forwarder.key).toBe(SIMPLE_LOGIN_FORWARDER); - }); - - describe("defaults$", () => { - it("should return the default subaddress options", async () => { - const strategy = new SimpleLoginForwarder(null, null, null, null, null); - - const result = await firstValueFrom(strategy.defaults$(SomeUser)); - - expect(result).toEqual(DefaultSimpleLoginOptions); - }); - }); - - describe("generate(string | null, SelfHostedApiOptions & EmailDomainOptions)", () => { - it.each([null, ""])("throws an error if the token is missing (token = %p)", async (token) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new SimpleLoginForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token, - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith( - "forwaderInvalidToken", - Forwarders.SimpleLogin.name, - ); - }); - - it.each([null, ""])( - "throws an error if the baseUrl is missing (baseUrl = %p)", - async (baseUrl) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new SimpleLoginForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - baseUrl, - }), - ).rejects.toEqual("forwarderNoUrl"); - - expect(apiService.nativeFetch).not.toHaveBeenCalled(); - expect(i18nService.t).toHaveBeenCalledWith("forwarderNoUrl", Forwarders.SimpleLogin.name); - }, - ); - - it.each([ - ["forwarderGeneratedByWithWebsite", "provided", "bitwarden.com", "bitwarden.com"], - ["forwarderGeneratedByWithWebsite", "provided", "httpbin.org", "httpbin.org"], - ["forwarderGeneratedBy", "not provided", null, ""], - ["forwarderGeneratedBy", "not provided", "", ""], - ])( - "describes the website with %p when the website is %s (= %p)", - async (translationKey, _ignored, website, expectedWebsite) => { - const apiService = mockApiService(200, {}); - const i18nService = mockI18nService(); - - const forwarder = new SimpleLoginForwarder(apiService, i18nService, null, null, null); - - await forwarder.generate({ - website, - token: "token", - baseUrl: "https://api.example.com", - }); - - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenCalledWith(translationKey, expectedWebsite); - }, - ); - - it.each([ - ["jane.doe@example.com", 201], - ["john.doe@example.com", 201], - ["jane.doe@example.com", 200], - ["john.doe@example.com", 200], - ])( - "returns the generated email address (= %p) if the request is successful (status = %p)", - async (alias, status) => { - const apiService = mockApiService(status, { alias }); - const i18nService = mockI18nService(); - - const forwarder = new SimpleLoginForwarder(apiService, i18nService, null, null, null); - - const result = await forwarder.generate({ - website: null, - token: "token", - baseUrl: "https://api.example.com", - }); - - expect(result).toEqual(alias); - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - }, - ); - - it("throws an invalid token error if the request fails with a 401", async () => { - const apiService = mockApiService(401, {}); - const i18nService = mockI18nService(); - - const forwarder = new SimpleLoginForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwaderInvalidToken"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwaderInvalidToken", - Forwarders.SimpleLogin.name, - ); - }); - - it.each([{}, null])( - "throws an unknown error if the request fails and no status (=%p) is provided", - async (body) => { - const apiService = mockApiService(500, body); - const i18nService = mockI18nService(); - - const forwarder = new SimpleLoginForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwarderUnknownError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderUnknownError", - Forwarders.SimpleLogin.name, - ); - }, - ); - - it.each([ - [100, "Continue"], - [202, "Accepted"], - [300, "Multiple Choices"], - [418, "I'm a teapot"], - [500, "Internal Server Error"], - [600, "Unknown Status"], - ])( - "throws an error with the status text if the request returns any other status code (= %i) and a status (= %p) is provided", - async (statusCode, error) => { - const apiService = mockApiService(statusCode, { error }); - const i18nService = mockI18nService(); - - const forwarder = new SimpleLoginForwarder(apiService, i18nService, null, null, null); - - await expect( - async () => - await forwarder.generate({ - website: null, - token: "token", - baseUrl: "https://api.example.com", - }), - ).rejects.toEqual("forwarderError"); - - expect(apiService.nativeFetch).toHaveBeenCalledWith(expect.any(Request)); - // counting instances is terribly flaky over changes, but jest doesn't have a better way to do this - expect(i18nService.t).toHaveBeenNthCalledWith( - 2, - "forwarderError", - Forwarders.SimpleLogin.name, - error, - ); - }, - ); - }); -}); diff --git a/libs/tools/generator/core/src/strategies/forwarders/simple-login.ts b/libs/tools/generator/core/src/strategies/forwarders/simple-login.ts deleted file mode 100644 index 30723b19e6c..00000000000 --- a/libs/tools/generator/core/src/strategies/forwarders/simple-login.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { StateProvider } from "@bitwarden/common/platform/state"; - -import { Forwarders, DefaultSimpleLoginOptions } from "../../data"; -import { SelfHostedApiOptions } from "../../types"; -import { ForwarderGeneratorStrategy } from "../forwarder-generator-strategy"; -import { SIMPLE_LOGIN_FORWARDER, SIMPLE_LOGIN_BUFFER } from "../storage"; - -/** Generates a forwarding address for Simple Login */ -export class SimpleLoginForwarder extends ForwarderGeneratorStrategy<SelfHostedApiOptions> { - /** Instantiates the forwarder - * @param apiService used for ajax requests to the forwarding service - * @param i18nService used to look up error strings - * @param encryptService protects sensitive forwarder options - * @param keyService looks up the user key when protecting data. - * @param stateProvider creates the durable state for options storage - */ - constructor( - private apiService: ApiService, - private i18nService: I18nService, - encryptService: EncryptService, - keyService: CryptoService, - stateProvider: StateProvider, - ) { - super(encryptService, keyService, stateProvider, DefaultSimpleLoginOptions); - } - - // configuration - readonly key = SIMPLE_LOGIN_FORWARDER; - readonly rolloverKey = SIMPLE_LOGIN_BUFFER; - - // request - generate = async (options: SelfHostedApiOptions) => { - if (!options.token || options.token === "") { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.SimpleLogin.name); - throw error; - } - if (!options.baseUrl || options.baseUrl === "") { - const error = this.i18nService.t("forwarderNoUrl", Forwarders.SimpleLogin.name); - throw error; - } - - let url = options.baseUrl + "/api/alias/random/new"; - let noteId = "forwarderGeneratedBy"; - if (options.website && options.website !== "") { - url += "?hostname=" + options.website; - noteId = "forwarderGeneratedByWithWebsite"; - } - const note = this.i18nService.t(noteId, options.website ?? ""); - - const request = new Request(url, { - redirect: "manual", - cache: "no-store", - method: "POST", - headers: new Headers({ - Authentication: options.token, - "Content-Type": "application/json", - }), - body: JSON.stringify({ note }), - }); - - const response = await this.apiService.nativeFetch(request); - if (response.status === 401) { - const error = this.i18nService.t("forwaderInvalidToken", Forwarders.SimpleLogin.name); - throw error; - } - - const json = await response.json(); - if (response.status === 200 || response.status === 201) { - return json.alias; - } else if (json?.error) { - const error = this.i18nService.t("forwarderError", Forwarders.SimpleLogin.name, json.error); - throw error; - } else { - const error = this.i18nService.t("forwarderUnknownError", Forwarders.SimpleLogin.name); - throw error; - } - }; -} - -export const DefaultOptions = Object.freeze({ - website: null, - baseUrl: "https://app.simplelogin.io", - token: "", -}); diff --git a/libs/tools/generator/core/src/strategies/index.ts b/libs/tools/generator/core/src/strategies/index.ts index 61c6a3ef209..01a204d4ad7 100644 --- a/libs/tools/generator/core/src/strategies/index.ts +++ b/libs/tools/generator/core/src/strategies/index.ts @@ -1,11 +1,6 @@ +export { ForwarderGeneratorStrategy } from "./forwarder-generator-strategy"; export { PassphraseGeneratorStrategy } from "./passphrase-generator-strategy"; export { PasswordGeneratorStrategy } from "./password-generator-strategy"; export { CatchallGeneratorStrategy } from "./catchall-generator-strategy"; export { SubaddressGeneratorStrategy } from "./subaddress-generator-strategy"; export { EffUsernameGeneratorStrategy } from "./eff-username-generator-strategy"; -export { AddyIoForwarder } from "./forwarders/addy-io"; -export { DuckDuckGoForwarder } from "./forwarders/duck-duck-go"; -export { FastmailForwarder } from "./forwarders/fastmail"; -export { FirefoxRelayForwarder } from "./forwarders/firefox-relay"; -export { ForwardEmailForwarder } from "./forwarders/forward-email"; -export { SimpleLoginForwarder } from "./forwarders/simple-login"; diff --git a/libs/tools/generator/core/src/strategies/options-classifier.spec.ts b/libs/tools/generator/core/src/strategies/options-classifier.spec.ts new file mode 100644 index 00000000000..148c1aa3e95 --- /dev/null +++ b/libs/tools/generator/core/src/strategies/options-classifier.spec.ts @@ -0,0 +1,60 @@ +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; + +import { OptionsClassifier } from "./options-classifier"; + +type SomeSettings = { foo: string }; +type SomeOptions = IntegrationRequest & SomeSettings; + +describe("OptionsClassifier", () => { + describe("classify", () => { + it("classifies properties from its input to the secret", () => { + const classifier = new OptionsClassifier<SomeSettings, SomeOptions>(); + + const result = classifier.classify({ foo: "bar", website: null }); + + expect(result.secret).toMatchObject({ foo: "bar" }); + }); + + it("omits the website property from the secret", () => { + const classifier = new OptionsClassifier<SomeSettings, SomeOptions>(); + + const result = classifier.classify({ foo: "bar", website: "www.example.com" }); + + expect(result.secret).not.toHaveProperty("website"); + }); + + it("has no disclosed data", () => { + const classifier = new OptionsClassifier<SomeSettings, SomeOptions>(); + + const result = classifier.classify({ foo: "bar", website: "www.example.com" }); + + expect(result.disclosed).toEqual({}); + }); + }); + + describe("declassify", () => { + it("copies properties from secret to its output", () => { + const classifier = new OptionsClassifier<SomeSettings, SomeOptions>(); + + const result = classifier.declassify(null, { foo: "bar" }); + + expect(result).toMatchObject({ foo: "bar" }); + }); + + it("adds a website property to its output", () => { + const classifier = new OptionsClassifier<SomeSettings, SomeOptions>(); + + const result = classifier.declassify(null, { foo: "bar" }); + + expect(result).toMatchObject({ website: null }); + }); + + it("ignores disclosed data", () => { + const classifier = new OptionsClassifier<SomeSettings, SomeOptions>(); + + const result = classifier.declassify({ foo: "biz" }, { foo: "bar" }); + + expect(result).toEqual({ foo: "bar", website: null }); + }); + }); +}); diff --git a/libs/tools/generator/core/src/strategies/options-classifier.ts b/libs/tools/generator/core/src/strategies/options-classifier.ts new file mode 100644 index 00000000000..0ad2495906c --- /dev/null +++ b/libs/tools/generator/core/src/strategies/options-classifier.ts @@ -0,0 +1,44 @@ +import { Jsonify } from "type-fest"; + +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; +import { Classifier } from "@bitwarden/common/tools/state/classifier"; + +/** Classifies an object by excluding IntegrationRequest parameters. + */ +export class OptionsClassifier< + Settings, + Options extends IntegrationRequest & Settings = IntegrationRequest & Settings, +> implements Classifier<Options, Record<string, never>, Settings> +{ + /** Partitions `secret` into its disclosed properties and secret properties. + * @param value The object to partition + * @returns an object that classifies secrets. + * The `disclosed` member is new and contains disclosed properties. + * The `secret` member is a copy of the secret parameter, including its + * prototype, with all disclosed and excluded properties deleted. + */ + classify(value: Options) { + const secret = JSON.parse(JSON.stringify(value)); + delete secret.website; + const disclosed: Record<string, never> = {}; + return { disclosed, secret }; + } + + /** Merges the properties of `secret` and `disclosed`. When `secret` and + * `disclosed` contain the same property, the `secret` property overrides + * the `disclosed` property. + * @param disclosed an object whose disclosed properties are merged into + * the output. Unknown properties are ignored. + * @param secret an objects whose properties are merged into the output. + * Excluded properties are ignored. Unknown properties are retained. + * @returns a new object containing the merged data. + * + * @remarks Declassified data is always jsonified--the purpose of classifying it is + * to Jsonify it, + * which causes type conversions. + */ + declassify(_disclosed: Jsonify<Record<keyof Settings, never>>, secret: Jsonify<Settings>) { + const result = { ...(secret as any), website: null }; + return result as Jsonify<Options>; + } +} diff --git a/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts b/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts index 78d7ed42a84..fe2731f9dd5 100644 --- a/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts @@ -6,7 +6,7 @@ import { DefaultPassphraseBoundaries, DefaultPassphraseGenerationOptions, Polici import { PasswordRandomizer } from "../engine"; import { mapPolicyToEvaluator } from "../rx"; import { PassphraseGenerationOptions, PassphraseGeneratorPolicy } from "../types"; -import { clone$PerUserId, sharedStateByUserId } from "../util"; +import { observe$PerUserId, sharedStateByUserId } from "../util"; import { PASSPHRASE_SETTINGS } from "./storage"; @@ -25,7 +25,7 @@ export class PassphraseGeneratorStrategy // configuration durableState = sharedStateByUserId(PASSPHRASE_SETTINGS, this.stateProvider); - defaults$ = clone$PerUserId(DefaultPassphraseGenerationOptions); + defaults$ = observe$PerUserId(() => DefaultPassphraseGenerationOptions); readonly policy = PolicyType.PasswordGenerator; toEvaluator() { return mapPolicyToEvaluator(Policies.Passphrase); diff --git a/libs/tools/generator/core/src/strategies/password-generator-strategy.ts b/libs/tools/generator/core/src/strategies/password-generator-strategy.ts index 587c5609e04..9ed62490c06 100644 --- a/libs/tools/generator/core/src/strategies/password-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/password-generator-strategy.ts @@ -6,7 +6,7 @@ import { Policies, DefaultPasswordGenerationOptions } from "../data"; import { PasswordRandomizer } from "../engine"; import { mapPolicyToEvaluator } from "../rx"; import { PasswordGenerationOptions, PasswordGeneratorPolicy } from "../types"; -import { clone$PerUserId, sharedStateByUserId, sum } from "../util"; +import { observe$PerUserId, sharedStateByUserId, sum } from "../util"; import { PASSWORD_SETTINGS } from "./storage"; @@ -24,7 +24,7 @@ export class PasswordGeneratorStrategy // configuration durableState = sharedStateByUserId(PASSWORD_SETTINGS, this.stateProvider); - defaults$ = clone$PerUserId(DefaultPasswordGenerationOptions); + defaults$ = observe$PerUserId(() => DefaultPasswordGenerationOptions); readonly policy = PolicyType.PasswordGenerator; toEvaluator() { return mapPolicyToEvaluator(Policies.Password); diff --git a/libs/tools/generator/core/src/strategies/storage.spec.ts b/libs/tools/generator/core/src/strategies/storage.spec.ts index 4a11d5887e9..ce739bf7d8b 100644 --- a/libs/tools/generator/core/src/strategies/storage.spec.ts +++ b/libs/tools/generator/core/src/strategies/storage.spec.ts @@ -4,18 +4,6 @@ import { SUBADDRESS_SETTINGS, PASSPHRASE_SETTINGS, PASSWORD_SETTINGS, - SIMPLE_LOGIN_FORWARDER, - FORWARD_EMAIL_FORWARDER, - FIREFOX_RELAY_FORWARDER, - FASTMAIL_FORWARDER, - DUCK_DUCK_GO_FORWARDER, - ADDY_IO_FORWARDER, - ADDY_IO_BUFFER, - DUCK_DUCK_GO_BUFFER, - FASTMAIL_BUFFER, - FIREFOX_RELAY_BUFFER, - FORWARD_EMAIL_BUFFER, - SIMPLE_LOGIN_BUFFER, } from "./storage"; describe("Key definitions", () => { @@ -58,112 +46,4 @@ describe("Key definitions", () => { expect(result).toBe(value); }); }); - - describe("ADDY_IO_FORWARDER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - const result = ADDY_IO_FORWARDER.deserializer(value); - expect(result).toBe(value); - }); - }); - - describe("DUCK_DUCK_GO_FORWARDER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - const result = DUCK_DUCK_GO_FORWARDER.deserializer(value); - expect(result).toBe(value); - }); - }); - - describe("FASTMAIL_FORWARDER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - const result = FASTMAIL_FORWARDER.deserializer(value); - expect(result).toBe(value); - }); - }); - - describe("FIREFOX_RELAY_FORWARDER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - const result = FIREFOX_RELAY_FORWARDER.deserializer(value); - expect(result).toBe(value); - }); - }); - - describe("FORWARD_EMAIL_FORWARDER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - const result = FORWARD_EMAIL_FORWARDER.deserializer(value); - expect(result).toBe(value); - }); - }); - - describe("SIMPLE_LOGIN_FORWARDER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - const result = SIMPLE_LOGIN_FORWARDER.deserializer(value); - expect(result).toBe(value); - }); - }); - - describe("ADDY_IO_BUFFER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - - const result = ADDY_IO_BUFFER.options.deserializer(value); - - expect(result).toBe(value); - }); - }); - - describe("DUCK_DUCK_GO_BUFFER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - - const result = DUCK_DUCK_GO_BUFFER.options.deserializer(value); - - expect(result).toBe(value); - }); - }); - - describe("FASTMAIL_BUFFER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - - const result = FASTMAIL_BUFFER.options.deserializer(value); - - expect(result).toBe(value); - }); - }); - - describe("FIREFOX_RELAY_BUFFER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - - const result = FIREFOX_RELAY_BUFFER.options.deserializer(value); - - expect(result).toBe(value); - }); - }); - - describe("FORWARD_EMAIL_BUFFER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - - const result = FORWARD_EMAIL_BUFFER.options.deserializer(value); - - expect(result).toBe(value); - }); - }); - - describe("SIMPLE_LOGIN_BUFFER", () => { - it("should pass through deserialization", () => { - const value: any = {}; - - const result = SIMPLE_LOGIN_BUFFER.options.deserializer(value); - - expect(result).toBe(value); - }); - }); }); diff --git a/libs/tools/generator/core/src/strategies/storage.ts b/libs/tools/generator/core/src/strategies/storage.ts index 5bb746ff94e..014a3224348 100644 --- a/libs/tools/generator/core/src/strategies/storage.ts +++ b/libs/tools/generator/core/src/strategies/storage.ts @@ -1,15 +1,10 @@ import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state"; -import { BufferedKeyDefinition } from "@bitwarden/common/tools/state/buffered-key-definition"; import { PassphraseGenerationOptions, PasswordGenerationOptions, CatchallGenerationOptions, EffUsernameGenerationOptions, - ApiOptions, - EmailDomainOptions, - EmailPrefixOptions, - SelfHostedApiOptions, SubaddressGenerationOptions, } from "../types"; @@ -62,123 +57,3 @@ export const SUBADDRESS_SETTINGS = new UserKeyDefinition<SubaddressGenerationOpt clearOn: [], }, ); - -/** backing store configuration for {@link Forwarders.AddyIo} */ -export const ADDY_IO_FORWARDER = new UserKeyDefinition<SelfHostedApiOptions & EmailDomainOptions>( - GENERATOR_DISK, - "addyIoForwarder", - { - deserializer: (value) => value, - clearOn: [], - }, -); - -/** backing store configuration for {@link Forwarders.DuckDuckGo} */ -export const DUCK_DUCK_GO_FORWARDER = new UserKeyDefinition<ApiOptions>( - GENERATOR_DISK, - "duckDuckGoForwarder", - { - deserializer: (value) => value, - clearOn: [], - }, -); - -/** backing store configuration for {@link Forwarders.FastMail} */ -export const FASTMAIL_FORWARDER = new UserKeyDefinition<ApiOptions & EmailPrefixOptions>( - GENERATOR_DISK, - "fastmailForwarder", - { - deserializer: (value) => value, - clearOn: [], - }, -); - -/** backing store configuration for {@link Forwarders.FireFoxRelay} */ -export const FIREFOX_RELAY_FORWARDER = new UserKeyDefinition<ApiOptions>( - GENERATOR_DISK, - "firefoxRelayForwarder", - { - deserializer: (value) => value, - clearOn: [], - }, -); - -/** backing store configuration for {@link Forwarders.ForwardEmail} */ -export const FORWARD_EMAIL_FORWARDER = new UserKeyDefinition<ApiOptions & EmailDomainOptions>( - GENERATOR_DISK, - "forwardEmailForwarder", - { - deserializer: (value) => value, - clearOn: [], - }, -); - -/** backing store configuration for {@link forwarders.SimpleLogin} */ -export const SIMPLE_LOGIN_FORWARDER = new UserKeyDefinition<SelfHostedApiOptions>( - GENERATOR_DISK, - "simpleLoginForwarder", - { - deserializer: (value) => value, - clearOn: [], - }, -); - -/** backing store configuration for {@link Forwarders.AddyIo} */ -export const ADDY_IO_BUFFER = new BufferedKeyDefinition<SelfHostedApiOptions & EmailDomainOptions>( - GENERATOR_DISK, - "addyIoBuffer", - { - deserializer: (value) => value, - clearOn: ["logout"], - }, -); - -/** backing store configuration for {@link Forwarders.DuckDuckGo} */ -export const DUCK_DUCK_GO_BUFFER = new BufferedKeyDefinition<ApiOptions>( - GENERATOR_DISK, - "duckDuckGoBuffer", - { - deserializer: (value) => value, - clearOn: ["logout"], - }, -); - -/** backing store configuration for {@link Forwarders.FastMail} */ -export const FASTMAIL_BUFFER = new BufferedKeyDefinition<ApiOptions & EmailPrefixOptions>( - GENERATOR_DISK, - "fastmailBuffer", - { - deserializer: (value) => value, - clearOn: ["logout"], - }, -); - -/** backing store configuration for {@link Forwarders.FireFoxRelay} */ -export const FIREFOX_RELAY_BUFFER = new BufferedKeyDefinition<ApiOptions>( - GENERATOR_DISK, - "firefoxRelayBuffer", - { - deserializer: (value) => value, - clearOn: ["logout"], - }, -); - -/** backing store configuration for {@link Forwarders.ForwardEmail} */ -export const FORWARD_EMAIL_BUFFER = new BufferedKeyDefinition<ApiOptions & EmailDomainOptions>( - GENERATOR_DISK, - "forwardEmailBuffer", - { - deserializer: (value) => value, - clearOn: ["logout"], - }, -); - -/** backing store configuration for {@link forwarders.SimpleLogin} */ -export const SIMPLE_LOGIN_BUFFER = new BufferedKeyDefinition<SelfHostedApiOptions>( - GENERATOR_DISK, - "simpleLoginBuffer", - { - deserializer: (value) => value, - clearOn: ["logout"], - }, -); diff --git a/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.ts b/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.ts index 645b15a6501..396b9d1922e 100644 --- a/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/subaddress-generator-strategy.ts @@ -6,7 +6,7 @@ import { DefaultSubaddressOptions } from "../data"; import { EmailCalculator, EmailRandomizer } from "../engine"; import { newDefaultEvaluator } from "../rx"; import { SubaddressGenerationOptions, NoPolicy } from "../types"; -import { clone$PerUserId, sharedStateByUserId } from "../util"; +import { observe$PerUserId, sharedStateByUserId } from "../util"; import { SUBADDRESS_SETTINGS } from "./storage"; @@ -30,7 +30,7 @@ export class SubaddressGeneratorStrategy // configuration durableState = sharedStateByUserId(SUBADDRESS_SETTINGS, this.stateProvider); - defaults$ = clone$PerUserId(this.defaultOptions); + defaults$ = observe$PerUserId(() => this.defaultOptions); toEvaluator = newDefaultEvaluator<SubaddressGenerationOptions>(); readonly policy = PolicyType.PasswordGenerator; diff --git a/libs/tools/generator/core/src/types/catchall-generator-options.ts b/libs/tools/generator/core/src/types/catchall-generator-options.ts index 157bb7fa93f..6f774ba65d3 100644 --- a/libs/tools/generator/core/src/types/catchall-generator-options.ts +++ b/libs/tools/generator/core/src/types/catchall-generator-options.ts @@ -1,4 +1,5 @@ -import { RequestOptions } from "./forwarder-options"; +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; + import { UsernameGenerationMode } from "./generator-options"; /** Settings supported when generating an email subaddress */ @@ -11,4 +12,4 @@ export type CatchallGenerationOptions = { * is `jd`, then the generated email address will be `jd@mydomain.io` */ catchallDomain?: string; -} & RequestOptions; +} & IntegrationRequest; diff --git a/libs/tools/generator/core/src/types/eff-username-generator-options.ts b/libs/tools/generator/core/src/types/eff-username-generator-options.ts index 812cad2c43d..e4a54397ed8 100644 --- a/libs/tools/generator/core/src/types/eff-username-generator-options.ts +++ b/libs/tools/generator/core/src/types/eff-username-generator-options.ts @@ -1,4 +1,4 @@ -import { RequestOptions } from "./forwarder-options"; +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; /** Settings supported when generating a username using the EFF word list */ export type EffUsernameGenerationOptions = { @@ -7,4 +7,4 @@ export type EffUsernameGenerationOptions = { /** when true, a random number is appended to the username */ wordIncludeNumber?: boolean; -} & RequestOptions; +} & IntegrationRequest; diff --git a/libs/tools/generator/core/src/types/forwarder-options.ts b/libs/tools/generator/core/src/types/forwarder-options.ts index f36a58a0db4..7ba04da99a8 100644 --- a/libs/tools/generator/core/src/types/forwarder-options.ts +++ b/libs/tools/generator/core/src/types/forwarder-options.ts @@ -1,14 +1,17 @@ +import { IntegrationId } from "@bitwarden/common/tools/integration"; +import { + ApiSettings, + IntegrationRequest, + SelfHostedApiSettings, +} from "@bitwarden/common/tools/integration/rpc"; + +import { EmailDomainSettings, EmailPrefixSettings } from "../engine"; + /** Identifiers for email forwarding services. * @remarks These are used to select forwarder-specific options. * The must be kept in sync with the forwarder implementations. */ -export type ForwarderId = - | "anonaddy" - | "duckduckgo" - | "fastmail" - | "firefoxrelay" - | "forwardemail" - | "simplelogin"; +export type ForwarderId = IntegrationId; /** Metadata format for email forwarding services. */ export type ForwarderMetadata = { @@ -23,50 +26,13 @@ export type ForwarderMetadata = { }; /** Options common to all forwarder APIs */ -export type ApiOptions = { - /** bearer token that authenticates bitwarden to the forwarder. - * This is required to issue an API request. - */ - token?: string; -} & RequestOptions; - -/** Options that provide contextual information about the application state - * when a forwarder is invoked. - * @remarks these fields should always be omitted when saving options. - */ -export type RequestOptions = { - /** @param website The domain of the website the generated email is used - * within. This should be set to `null` when the request is not specific - * to any website. - */ - website: string | null; -}; +export type ApiOptions = ApiSettings & IntegrationRequest; /** Api configuration for forwarders that support self-hosted installations. */ -export type SelfHostedApiOptions = ApiOptions & { - /** The base URL of the forwarder's API. - * When this is empty, the forwarder's default production API is used. - */ - baseUrl: string; -}; +export type SelfHostedApiOptions = SelfHostedApiSettings & IntegrationRequest; /** Api configuration for forwarders that support custom domains. */ -export type EmailDomainOptions = { - /** The domain part of the generated email address. - * @remarks The domain should be authorized by the forwarder before - * submitting a request through bitwarden. - * @example If the domain is `domain.io` and the generated username - * is `jd`, then the generated email address will be `jd@mydomain.io` - */ - domain: string; -}; +export type EmailDomainOptions = EmailDomainSettings; /** Api configuration for forwarders that support custom email parts. */ -export type EmailPrefixOptions = EmailDomainOptions & { - /** A prefix joined to the generated email address' username. - * @example If the prefix is `foo`, the generated username is `bar`, - * and the domain is `domain.io`, then the generated email address is ` - * then the generated username is `foobar@domain.io`. - */ - prefix: string; -}; +export type EmailPrefixOptions = EmailDomainSettings & EmailPrefixSettings; diff --git a/libs/tools/generator/core/src/types/subaddress-generator-options.ts b/libs/tools/generator/core/src/types/subaddress-generator-options.ts index 67b545d2fb5..2ff088facb5 100644 --- a/libs/tools/generator/core/src/types/subaddress-generator-options.ts +++ b/libs/tools/generator/core/src/types/subaddress-generator-options.ts @@ -1,4 +1,5 @@ -import { RequestOptions } from "./forwarder-options"; +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; + import { UsernameGenerationMode } from "./generator-options"; /** Settings supported when generating an email subaddress */ @@ -8,4 +9,4 @@ export type SubaddressGenerationOptions = { /** the email address the subaddress is applied to. */ subaddressEmail?: string; -} & RequestOptions; +} & IntegrationRequest; diff --git a/libs/tools/generator/core/src/util.ts b/libs/tools/generator/core/src/util.ts index c62591a2ae8..cca2c75834c 100644 --- a/libs/tools/generator/core/src/util.ts +++ b/libs/tools/generator/core/src/util.ts @@ -1,4 +1,4 @@ -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject, Observable } from "rxjs"; import { SingleUserState, @@ -8,14 +8,17 @@ import { import { UserId } from "@bitwarden/common/types/guid"; /** construct a method that outputs a copy of `defaultValue` as an observable. */ -export function clone$PerUserId<Value>(defaultValue: Value) { +export function observe$PerUserId<Value>( + create: () => Partial<Value>, +): (key: UserId) => Observable<Value> { const _subjects = new Map<UserId, BehaviorSubject<Value>>(); return (key: UserId) => { let value = _subjects.get(key); if (value === undefined) { - value = new BehaviorSubject({ ...defaultValue }); + const initialValue = create(); + value = new BehaviorSubject({ ...initialValue } as Value); _subjects.set(key, value); } diff --git a/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts b/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts index 1bcf5403564..8626ef81f90 100644 --- a/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts +++ b/libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts @@ -5,7 +5,8 @@ import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.se import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { StateProvider } from "@bitwarden/common/platform/state"; -import { engine, services, strategies } from "@bitwarden/generator-core"; +import { RestClient } from "@bitwarden/common/tools/integration/rpc"; +import { engine, services, strategies, Integrations } from "@bitwarden/generator-core"; import { DefaultGeneratorNavigationService } from "@bitwarden/generator-navigation"; import { LegacyUsernameGenerationService } from "./legacy-username-generation.service"; @@ -17,12 +18,7 @@ const { CatchallGeneratorStrategy, SubaddressGeneratorStrategy, EffUsernameGeneratorStrategy, - AddyIoForwarder, - DuckDuckGoForwarder, - FastmailForwarder, - FirefoxRelayForwarder, - ForwardEmailForwarder, - SimpleLoginForwarder, + ForwarderGeneratorStrategy, } = strategies; export function legacyUsernameGenerationServiceFactory( @@ -35,6 +31,7 @@ export function legacyUsernameGenerationServiceFactory( stateProvider: StateProvider, ): UsernameGenerationServiceAbstraction { const randomizer = new CryptoServiceRandomizer(cryptoService); + const restClient = new RestClient(apiService, i18nService); const usernameRandomizer = new UsernameRandomizer(randomizer); const emailRandomizer = new EmailRandomizer(randomizer); const emailCalculator = new EmailCalculator(); @@ -55,23 +52,45 @@ export function legacyUsernameGenerationServiceFactory( ); const addyIo = new DefaultGeneratorService( - new AddyIoForwarder(apiService, i18nService, encryptService, cryptoService, stateProvider), + new ForwarderGeneratorStrategy( + Integrations.AddyIo, + restClient, + i18nService, + encryptService, + cryptoService, + stateProvider, + ), policyService, ); const duckDuckGo = new DefaultGeneratorService( - new DuckDuckGoForwarder(apiService, i18nService, encryptService, cryptoService, stateProvider), + new ForwarderGeneratorStrategy( + Integrations.DuckDuckGo, + restClient, + i18nService, + encryptService, + cryptoService, + stateProvider, + ), policyService, ); const fastmail = new DefaultGeneratorService( - new FastmailForwarder(apiService, i18nService, encryptService, cryptoService, stateProvider), + new ForwarderGeneratorStrategy( + Integrations.Fastmail, + restClient, + i18nService, + encryptService, + cryptoService, + stateProvider, + ), policyService, ); const firefoxRelay = new DefaultGeneratorService( - new FirefoxRelayForwarder( - apiService, + new ForwarderGeneratorStrategy( + Integrations.FirefoxRelay, + restClient, i18nService, encryptService, cryptoService, @@ -81,8 +100,9 @@ export function legacyUsernameGenerationServiceFactory( ); const forwardEmail = new DefaultGeneratorService( - new ForwardEmailForwarder( - apiService, + new ForwarderGeneratorStrategy( + Integrations.ForwardEmail, + restClient, i18nService, encryptService, cryptoService, @@ -92,7 +112,14 @@ export function legacyUsernameGenerationServiceFactory( ); const simpleLogin = new DefaultGeneratorService( - new SimpleLoginForwarder(apiService, i18nService, encryptService, cryptoService, stateProvider), + new ForwarderGeneratorStrategy( + Integrations.SimpleLogin, + restClient, + i18nService, + encryptService, + cryptoService, + stateProvider, + ), policyService, ); diff --git a/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts b/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts index b536666da59..57d618c04a4 100644 --- a/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts +++ b/libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.spec.ts @@ -1,6 +1,7 @@ import { mock } from "jest-mock-extended"; import { of } from "rxjs"; +import { IntegrationId } from "@bitwarden/common/tools/integration"; import { UserId } from "@bitwarden/common/types/guid"; import { GeneratorService, @@ -185,7 +186,7 @@ describe("LegacyPasswordGenerationService", () => { const navigation = createNavigationGenerator({ type: "passphrase", username: "word", - forwarder: "simplelogin", + forwarder: "simplelogin" as IntegrationId, }); const accountService = mockAccountServiceWith(SomeUser); const generator = new LegacyPasswordGenerationService( @@ -496,7 +497,7 @@ describe("LegacyPasswordGenerationService", () => { const navigation = createNavigationGenerator({ type: "password", username: "forwarded", - forwarder: "firefoxrelay", + forwarder: "firefoxrelay" as IntegrationId, }); const accountService = mockAccountServiceWith(SomeUser); const generator = new LegacyPasswordGenerationService( diff --git a/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts b/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts index ebe5f9074c8..08ffce2eba5 100644 --- a/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts +++ b/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.spec.ts @@ -23,6 +23,7 @@ import { DefaultSubaddressOptions, SubaddressGenerationOptions, policies, + Integrations, } from "@bitwarden/generator-core"; import { GeneratorNavigationPolicy, @@ -724,7 +725,7 @@ describe("LegacyUsernameGenerationService", () => { }); options.type = "forwarded"; - options.forwardedService = "anonaddy"; + options.forwardedService = Integrations.AddyIo.id; await generator.saveOptions(options); expect(addyIo.saveOptions).toHaveBeenCalledWith(SomeUser, { @@ -735,7 +736,7 @@ describe("LegacyUsernameGenerationService", () => { }); options.type = "forwarded"; - options.forwardedService = "duckduckgo"; + options.forwardedService = Integrations.DuckDuckGo.id; await generator.saveOptions(options); expect(duckDuckGo.saveOptions).toHaveBeenCalledWith(SomeUser, { @@ -744,7 +745,7 @@ describe("LegacyUsernameGenerationService", () => { }); options.type = "forwarded"; - options.forwardedService = "fastmail"; + options.forwardedService = Integrations.Fastmail.id; await generator.saveOptions(options); expect(fastmail.saveOptions).toHaveBeenCalledWith(SomeUser, { @@ -753,7 +754,7 @@ describe("LegacyUsernameGenerationService", () => { }); options.type = "forwarded"; - options.forwardedService = "firefoxrelay"; + options.forwardedService = Integrations.FirefoxRelay.id; await generator.saveOptions(options); expect(firefoxRelay.saveOptions).toHaveBeenCalledWith(SomeUser, { @@ -762,7 +763,7 @@ describe("LegacyUsernameGenerationService", () => { }); options.type = "forwarded"; - options.forwardedService = "forwardemail"; + options.forwardedService = Integrations.ForwardEmail.id; await generator.saveOptions(options); expect(forwardEmail.saveOptions).toHaveBeenCalledWith(SomeUser, { @@ -772,7 +773,7 @@ describe("LegacyUsernameGenerationService", () => { }); options.type = "forwarded"; - options.forwardedService = "simplelogin"; + options.forwardedService = Integrations.SimpleLogin.id; await generator.saveOptions(options); expect(simpleLogin.saveOptions).toHaveBeenCalledWith(SomeUser, { diff --git a/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.ts b/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.ts index ee9e5bce311..9be85f4eeaf 100644 --- a/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.ts +++ b/libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.ts @@ -1,12 +1,12 @@ import { zip, firstValueFrom, map, concatMap, combineLatest } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; import { UserId } from "@bitwarden/common/types/guid"; import { ApiOptions, EmailDomainOptions, EmailPrefixOptions, - RequestOptions, SelfHostedApiOptions, NoPolicy, GeneratorService, @@ -30,12 +30,12 @@ type MappedOptions = { subaddress: SubaddressGenerationOptions; }; forwarders: { - addyIo: SelfHostedApiOptions & EmailDomainOptions & RequestOptions; - duckDuckGo: ApiOptions & RequestOptions; - fastmail: ApiOptions & EmailPrefixOptions & RequestOptions; - firefoxRelay: ApiOptions & RequestOptions; - forwardEmail: ApiOptions & EmailDomainOptions & RequestOptions; - simpleLogin: SelfHostedApiOptions & RequestOptions; + addyIo: SelfHostedApiOptions & EmailDomainOptions & IntegrationRequest; + duckDuckGo: ApiOptions & IntegrationRequest; + fastmail: ApiOptions & EmailPrefixOptions & IntegrationRequest; + firefoxRelay: ApiOptions & IntegrationRequest; + forwardEmail: ApiOptions & EmailDomainOptions & IntegrationRequest; + simpleLogin: SelfHostedApiOptions & IntegrationRequest; }; }; diff --git a/libs/tools/generator/extensions/legacy/src/username-generation-options.ts b/libs/tools/generator/extensions/legacy/src/username-generation-options.ts index 9e153066c0a..211760988dd 100644 --- a/libs/tools/generator/extensions/legacy/src/username-generation-options.ts +++ b/libs/tools/generator/extensions/legacy/src/username-generation-options.ts @@ -1,6 +1,6 @@ +import { IntegrationRequest } from "@bitwarden/common/tools/integration/rpc"; import { ForwarderId, - RequestOptions, CatchallGenerationOptions, EffUsernameGenerationOptions, SubaddressGenerationOptions, @@ -10,7 +10,7 @@ import { export type UsernameGeneratorOptions = EffUsernameGenerationOptions & SubaddressGenerationOptions & CatchallGenerationOptions & - RequestOptions & { + IntegrationRequest & { type?: UsernameGeneratorType; forwardedService?: ForwarderId | ""; forwardedAnonAddyApiToken?: string; From 6896ef23927de9661c0b2f52d9634f8cfe70dfad Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:01:28 +0100 Subject: [PATCH 34/46] [AC-2708] Upgrading from a password manager only subscription (#10320) * Add changes for the upgrade dialog * Resolve the free org to any org type besides Families * Resolve the pr comments on navigation * resolve family plan upgrade from free --- .../members/members.component.ts | 49 +- .../change-plan-dialog.component.html | 383 ++++++++++ .../change-plan-dialog.component.ts | 658 ++++++++++++++++++ .../organization-billing.module.ts | 2 + ...ganization-subscription-cloud.component.ts | 26 +- .../app/billing/shared/tax-info.component.ts | 2 +- apps/web/src/locales/en/messages.json | 87 +++ libs/common/src/billing/enums/index.ts | 1 + .../src/billing/enums/plan-interval.enum.ts | 4 + .../billing/enums/product-tier-type.enum.ts | 8 + libs/common/src/enums/feature-flag.enum.ts | 2 + 11 files changed, 1213 insertions(+), 9 deletions(-) create mode 100644 apps/web/src/app/billing/organizations/change-plan-dialog.component.html create mode 100644 apps/web/src/app/billing/organizations/change-plan-dialog.component.ts create mode 100644 libs/common/src/billing/enums/plan-interval.enum.ts diff --git a/apps/web/src/app/admin-console/organizations/members/members.component.ts b/apps/web/src/app/admin-console/organizations/members/members.component.ts index 809f1e3935d..f5eee80d66a 100644 --- a/apps/web/src/app/admin-console/organizations/members/members.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/members.component.ts @@ -33,7 +33,9 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction"; -import { ProductTierType } from "@bitwarden/common/billing/enums"; +import { isNotSelfUpgradable, ProductTierType } from "@bitwarden/common/billing/enums"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -45,6 +47,10 @@ import { Collection } from "@bitwarden/common/vault/models/domain/collection"; import { CollectionDetailsResponse } from "@bitwarden/common/vault/models/response/collection.response"; import { DialogService, SimpleDialogOptions, ToastService } from "@bitwarden/components"; +import { + ChangePlanDialogResultType, + openChangePlanDialog, +} from "../../../billing/organizations/change-plan-dialog.component"; import { BaseMembersComponent } from "../../common/base-members.component"; import { PeopleTableDataSource } from "../../common/people-table-data-source"; import { GroupService } from "../core"; @@ -86,6 +92,10 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView> protected canUseSecretsManager$: Observable<boolean>; + protected EnableUpgradePasswordManagerSub$ = this.configService.getFeatureFlag$( + FeatureFlag.EnableUpgradePasswordManagerSub, + ); + // Fixed sizes used for cdkVirtualScroll protected rowHeight = 62; protected rowHeightClass = `tw-h-[62px]`; @@ -112,6 +122,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView> private collectionService: CollectionService, private billingApiService: BillingApiServiceAbstraction, private modalService: ModalService, + private configService: ConfigService, ) { super( apiService, @@ -375,6 +386,9 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView> case ProductTierType.TeamsStarter: product = "teamsStarterPlan"; break; + case ProductTierType.Families: + product = "familiesPlan"; + break; default: throw new Error(`Unsupported product type: ${productType}`); } @@ -395,7 +409,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView> const productType = this.organization.productTierType; - if (productType !== ProductTierType.Free && productType !== ProductTierType.TeamsStarter) { + if (isNotSelfUpgradable(productType)) { throw new Error(`Unsupported product type: ${productType}`); } @@ -409,7 +423,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView> const productType = this.organization.productTierType; - if (productType !== ProductTierType.Free && productType !== ProductTierType.TeamsStarter) { + if (isNotSelfUpgradable(productType)) { throw new Error(`Unsupported product type: ${this.organization.productTierType}`); } @@ -459,11 +473,32 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView> !user && this.dataSource.data.length === this.organization.seats && (this.organization.productTierType === ProductTierType.Free || - this.organization.productTierType === ProductTierType.TeamsStarter) + this.organization.productTierType === ProductTierType.TeamsStarter || + this.organization.productTierType === ProductTierType.Families) ) { - // Show org upgrade modal - await this.showSeatLimitReachedDialog(); - return; + const EnableUpgradePasswordManagerSub = await firstValueFrom( + this.EnableUpgradePasswordManagerSub$, + ); + if (EnableUpgradePasswordManagerSub) { + const reference = openChangePlanDialog(this.dialogService, { + data: { + organizationId: this.organization.id, + subscription: null, + productTierType: this.organization.productTierType, + }, + }); + + const result = await lastValueFrom(reference.closed); + + if (result === ChangePlanDialogResultType.Submitted) { + await this.load(); + } + return; + } else { + // Show org upgrade modal + await this.showSeatLimitReachedDialog(); + return; + } } const dialog = openUserAddEditDialog(this.dialogService, { diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html new file mode 100644 index 00000000000..0ca913a3b72 --- /dev/null +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html @@ -0,0 +1,383 @@ +<form [formGroup]="formGroup" [bitSubmit]="submit"> + <bit-dialog dialogSize="large" [loading]="loading"> + <span bitDialogTitle class="tw-font-semibold"> + {{ "upgradeFreeOrganization" | i18n: currentPlanName }} + </span> + <div bitDialogContent> + <p>{{ "upgradePlan" | i18n }}</p> + <div class="tw-mb-3"> + <span class="tw-text-lg tw-pr-1 tw-font-bold">{{ "selectAPlan" | i18n }}</span> + <bit-radio-group + formControlName="planInterval" + class="tw-flex tw-items-start tw-gap-5" + (change)="planTypeChanged()" + > + <bit-radio-button + class="tw-inline-block" + *ngFor="let planInterval of getPlanIntervals()" + id="plan-annually" + [value]="planInterval.value" + > + <bit-label> + <i class="bwi" aria-hidden="true"></i> + {{ planInterval.name }}&nbsp;<span + *ngIf=" + this.discountPercentageFromSub > 0 + ? discountPercentageFromSub + : this.discountPercentage && planInterval.value === 1 + " + bitBadge + variant="success" + >{{ + "upgradeDiscount" + | i18n + : (this.discountPercentageFromSub > 0 + ? discountPercentageFromSub + : this.discountPercentage) + }}</span + ></bit-label + > + </bit-radio-button> + </bit-radio-group> + </div> + <ng-container *ngIf="!loading && !selfHosted && this.passwordManagerPlans"> + <div + class="tw-grid tw-grid-flow-col tw-gap-4 tw-mb-4" + [class]="'tw-grid-cols-' + selectableProducts.length" + > + <div + *ngFor="let selectableProduct of selectableProducts; let i = index" + [ngClass]="getPlanCardContainerClasses(selectableProduct, i)" + (click)="selectPlan(selectableProduct)" + tabindex="0" + > + <div class="tw-relative"> + <div + *ngIf="selectableProduct == selectedPlan" + class="tw-bg-primary-600 tw-text-center !tw-text-contrast tw-text-sm tw-font-bold tw-py-1 group-hover:tw-bg-primary-700" + > + {{ "selected" | i18n }} + </div> + <div + class="tw-px-2 tw-py-4" + [ngClass]="{ 'tw-pt-10': !(selectableProduct == selectedPlan) }" + > + <h3 class="tw-text-lg tw-font-bold tw-uppercase"> + {{ selectableProduct.nameLocalizationKey | i18n }} + </h3> + <span *ngIf="selectableProduct.productTier != productTypes.Free"> + <ng-container + *ngIf="selectableProduct.PasswordManager.basePrice && !acceptingSponsorship" + > + <b class="tw-text-lg tw-font-semibold"> + {{ + (selectableProduct.isAnnual + ? selectableProduct.PasswordManager.basePrice / 12 + : selectableProduct.PasswordManager.basePrice + ) | currency: "$" + }} + </b> + <b class="tw-text-sm tw-font-semibold"> + /{{ "month" | i18n }} + {{ "includesXMembers" | i18n: selectableProduct.PasswordManager.baseSeats }} + <ng-container + *ngIf="selectableProduct.PasswordManager.hasAdditionalSeatsOption" + > + {{ ("additionalUsers" | i18n).toLowerCase() }} + {{ + (selectableProduct.isAnnual + ? selectableProduct.PasswordManager.seatPrice / 12 + : selectableProduct.PasswordManager.seatPrice + ) | currency: "$" + }} + /{{ "month" | i18n }} + </ng-container> + </b> + </ng-container> + </span> + <span + *ngIf=" + !selectableProduct.PasswordManager.basePrice && + selectableProduct.PasswordManager.hasAdditionalSeatsOption + " + > + <b class="tw-text-lg tw-font-semibold" + >{{ + "costPerMember" + | i18n + : ((selectableProduct.isAnnual + ? selectableProduct.PasswordManager.seatPrice / 12 + : selectableProduct.PasswordManager.seatPrice + ) + | currency: "$") + }} + </b> + <b class="tw-text-sm tw-font-semibold"> /{{ "monthPerMember" | i18n }}</b> + </span> + <span *ngIf="selectableProduct.productTier == productTypes.Free" + >{{ "freeForever" | i18n }} + </span> + </div> + </div> + + <ng-container + *ngIf=" + selectableProduct.productTier === productTypes.Enterprise; + else nonEnterprisePlans + " + > + <p class="tw-text-xs tw-px-2">{{ "upgradeEnterpriseMessage" | i18n }}</p> + <p class="tw-text-xs tw-px-2 tw-mb-0">{{ "includeAllTeamsFeatures" | i18n }}</p> + <ul class="tw-px-3 tw-pb-2 tw-list-inside tw-mb-0 tw-text-xs"> + <li *ngIf="selectableProduct.hasPolicies"> + {{ "includeEnterprisePolicies" | i18n }} + </li> + <li *ngIf="selectableProduct.hasSso"> + {{ "includeSsoAuthenticationMessage" | i18n }} + </li> + <li *ngIf="selectableProduct.hasSelfHost">{{ "optionalOnPremHosting" | i18n }}</li> + </ul> + </ng-container> + <ng-template #nonEnterprisePlans> + <ng-container + *ngIf=" + selectableProduct.productTier === productTypes.Teams && + teamsStarterPlanIsAvailable; + else fullFeatureList + " + > + <ul class="tw-px-2 tw-pb-2 tw-list-inside tw-mb-0 tw-text-xs"> + <li>{{ "includeAllTeamsStarterFeatures" | i18n }}</li> + <li>{{ "chooseMonthlyOrAnnualBilling" | i18n }}</li> + <li>{{ "abilityToAddMoreThanNMembers" | i18n: 10 }}</li> + </ul> + </ng-container> + <ng-template #fullFeatureList> + <p + *ngIf="selectableProduct.productTier === productTypes.Teams" + class="tw-text-xs tw-px-2" + > + {{ "upgradeTeamsMessage" | i18n }} + </p> + <p + *ngIf="selectableProduct.productTier === productTypes.Families" + class="tw-text-xs tw-px-2" + > + {{ "upgradeFamilyMessage" | i18n }} + </p> + <ul class="tw-px-2 tw-pb-2 tw-list-inside tw-mb-0 tw-text-xs"> + <li *ngIf="selectableProduct.productTier == productTypes.Free"> + {{ "limitedUsers" | i18n: selectableProduct.PasswordManager.maxSeats }} + </li> + <li *ngIf="!selectableProduct.PasswordManager.maxSeats"> + {{ "teamsInviteMessage" | i18n }} + </li> + <li *ngIf="selectableProduct.PasswordManager.maxCollections"> + {{ + "chooseMonthlyOrAnnualBilling" + | i18n: selectableProduct.PasswordManager.maxCollections + }} + </li> + <li *ngIf="!selectableProduct.PasswordManager.maxCollections"> + {{ "createUnlimitedCollections" | i18n }} + </li> + <li *ngIf="selectableProduct.hasGroups"> + {{ "accessToCreateGroups" | i18n }} + </li> + <li *ngIf="selectableProduct.hasDirectory"> + {{ "syncGroupsAndUsersFromDirectory" | i18n }} + </li> + <li *ngIf="selectableProduct.productTier == productTypes.Families"> + {{ "accessToPremiumFeatures" | i18n }} + </li> + <li *ngIf="selectableProduct.productTier == productTypes.Families"> + {{ "priorityCustomerSupport" | i18n }} + </li> + <li *ngIf="selectableProduct.hasSelfHost"> + {{ "optionalOnPremHosting" | i18n }} + </li> + </ul> + </ng-template> + </ng-template> + </div> + </div> + </ng-container> + + <!-- Payment info --> + <ng-container *ngIf="formGroup.value.productTier !== productTypes.Free"> + <h2 bitTypography="h4">{{ "paymentMethod" | i18n }}</h2> + <p *ngIf="!showPayment && billing.paymentSource"> + <i class="bwi bwi-fw" [ngClass]="paymentSourceClasses"></i> + {{ billing.paymentSource.description }} + <span class="ml-2 tw-text-primary-600 tw-cursor-pointer" (click)="toggleShowPayment()">{{ + "changePaymentMethod" | i18n + }}</span> + <a></a> + </p> + <app-payment + *ngIf="upgradeRequiresPaymentMethod || showPayment" + [hideCredit]="true" + ></app-payment> + <app-tax-info + *ngIf="showPayment || upgradeRequiresPaymentMethod" + (onCountryChanged)="changedCountry()" + ></app-tax-info> + <div id="price" class="tw-mt-4"> + <p class="tw-text-lg tw-mb-1"> + <span class="tw-font-semibold" + >{{ "total" | i18n }}: {{ total | currency: "USD" : "$" }} USD</span + > + <span class="tw-text-xs tw-font-light"> / {{ selectedPlanInterval | i18n }}</span> + <button + (click)="toggleTotalOpened()" + type="button" + [bitIconButton]="totalOpened ? 'bwi-angle-down' : 'bwi-angle-up'" + size="small" + aria-hidden="true" + ></button> + </p> + </div> + + <div *ngIf="totalOpened" class="row"> + <bit-hint class="col-6" *ngIf="selectedInterval == planIntervals.Annually"> + <p + class="tw-mb-0 tw-flex tw-justify-between" + bitTypography="body2" + *ngIf="selectedPlan.PasswordManager.basePrice" + > + <span> + {{ selectedPlan.PasswordManager.baseSeats }} + {{ "members" | i18n }} &times; + {{ + (selectedPlan.isAnnual + ? selectedPlan.PasswordManager.basePrice / 12 + : selectedPlan.PasswordManager.basePrice + ) | currency: "$" + }} + /{{ "year" | i18n }} + </span> + <span> + <ng-container *ngIf="acceptingSponsorship; else notAcceptingSponsorship"> + <span class="tw-line-through">{{ + selectedPlan.PasswordManager.basePrice | currency: "$" + }}</span> + {{ "freeWithSponsorship" | i18n }} + </ng-container> + <ng-template #notAcceptingSponsorship> + {{ selectedPlan.PasswordManager.basePrice | currency: "$" }} + </ng-template> + </span> + </p> + <p + class="tw-mb-0 tw-flex tw-justify-between" + bitTypography="body2" + *ngIf="selectedPlan.PasswordManager.hasAdditionalSeatsOption" + > + <span> + <span *ngIf="selectedPlan.PasswordManager.baseSeats" + >{{ "additionalUsers" | i18n }}:</span + > + {{ organization.seats || 0 }}&nbsp; + <span *ngIf="!selectedPlan.PasswordManager.baseSeats">{{ "members" | i18n }}</span> + &times; + {{ selectedPlan.PasswordManager.seatPrice | currency: "$" }} + /{{ "year" | i18n }} + </span> + + <span> + {{ passwordManagerSeatTotal(selectedPlan) | currency: "$" }} + </span> + </p> + <p + class="tw-mb-0 tw-flex tw-justify-between" + bitTypography="body2" + *ngIf="selectedPlan.PasswordManager.hasAdditionalStorageOption" + > + <span> + {{ 0 }} + {{ "additionalStorageGbMessage" | i18n }} + &times; + {{ selectedPlan.PasswordManager.additionalStoragePricePerGb | currency: "$" }} + /{{ "year" | i18n }} + </span> + <span>{{ 0 | currency: "$" }}</span> + </p> + </bit-hint> + <bit-hint class="col-6" *ngIf="selectedInterval == planIntervals.Monthly"> + <p + class="tw-mb-0 tw-flex tw-justify-between" + bitTypography="body2" + *ngIf="selectedPlan.PasswordManager.basePrice" + > + <span> + {{ "basePrice" | i18n }}: + {{ selectedPlan.PasswordManager.basePrice | currency: "$" }} + {{ "monthAbbr" | i18n }} + </span> + <span> + {{ selectedPlan.PasswordManager.basePrice | currency: "$" }} + </span> + </p> + <p + class="tw-mb-0 tw-flex tw-justify-between" + bitTypography="body2" + *ngIf="selectedPlan.PasswordManager.hasAdditionalSeatsOption" + > + <span> + <span *ngIf="selectedPlan.PasswordManager.baseSeats" + >{{ "additionalUsers" | i18n }}:</span + > + {{ formGroup.controls["additionalSeats"].value || 0 }}&nbsp; + <span *ngIf="!selectedPlan.PasswordManager.baseSeats">{{ "members" | i18n }}</span> + &times; + {{ selectedPlan.PasswordManager.seatPrice | currency: "$" }} + /{{ "month" | i18n }} + </span> + <span> + {{ passwordManagerSeatTotal(selectedPlan) | currency: "$" }} + </span> + </p> + <p + class="tw-mb-0 tw-flex tw-justify-between" + bitTypography="body2" + *ngIf="selectedPlan.PasswordManager.hasAdditionalStorageOption" + > + <span> + {{ 0 }} + {{ "additionalStorageGbMessage" | i18n }} + &times; + {{ selectedPlan.PasswordManager.additionalStoragePricePerGb | currency: "$" }} + /{{ "month" | i18n }} + </span> + <span>{{ 0 | currency: "$" }}</span> + </p> + </bit-hint> + </div> + + <div *ngIf="totalOpened" id="price" class="row tw-mt-4"> + <bit-hint class="col-6"> + <p + class="tw-flex tw-justify-between tw-border-0 tw-border-solid tw-border-t tw-border-secondary-300 tw-pt-2 tw-mb-0" + > + <span class="tw-font-semibold"> + {{ "total" | i18n }} + </span> + <span> + {{ total | currency: "USD" : "$" }} + <span class="tw-text-xs tw-font-light"> / {{ selectedPlanInterval | i18n }}</span> + </span> + </p> + </bit-hint> + </div> + </ng-container> + </div> + <ng-container bitDialogFooter> + <button bitButton bitFormButton buttonType="primary" type="submit"> + {{ "save" | i18n }} + </button> + <button bitButton buttonType="secondary" type="button" [bitDialogClose]="ResultType.Closed"> + {{ "cancel" | i18n }} + </button> + </ng-container> + </bit-dialog> +</form> diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts new file mode 100644 index 00000000000..98c980186ca --- /dev/null +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts @@ -0,0 +1,658 @@ +import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; +import { Component, EventEmitter, Inject, Input, OnInit, Output, ViewChild } from "@angular/core"; +import { FormBuilder, Validators } from "@angular/forms"; +import { Router } from "@angular/router"; +import { Subject, takeUntil } from "rxjs"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { PolicyType } from "@bitwarden/common/admin-console/enums"; +import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; +import { OrganizationUpgradeRequest } from "@bitwarden/common/admin-console/models/request/organization-upgrade.request"; +import { + PaymentMethodType, + PlanType, + ProductTierType, + PlanInterval, +} from "@bitwarden/common/billing/enums"; +import { PaymentRequest } from "@bitwarden/common/billing/models/request/payment.request"; +import { BillingResponse } from "@bitwarden/common/billing/models/response/billing.response"; +import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response"; +import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; +import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { DialogService, ToastService } from "@bitwarden/components"; + +import { PaymentComponent } from "../shared/payment.component"; +import { TaxInfoComponent } from "../shared/tax-info.component"; + +type ChangePlanDialogParams = { + organizationId: string; + subscription: OrganizationSubscriptionResponse; + productTierType: ProductTierType; +}; + +export enum ChangePlanDialogResultType { + Closed = "closed", + Submitted = "submitted", +} + +export enum PlanCardState { + Selected = "selected", + NotSelected = "not_selected", + Disabled = "disabled", +} + +export const openChangePlanDialog = ( + dialogService: DialogService, + dialogConfig: DialogConfig<ChangePlanDialogParams>, +) => + dialogService.open<ChangePlanDialogResultType, ChangePlanDialogParams>( + ChangePlanDialogComponent, + dialogConfig, + ); + +type PlanCard = { + name: string; + selected: boolean; +}; + +interface OnSuccessArgs { + organizationId: string; +} + +@Component({ + templateUrl: "./change-plan-dialog.component.html", +}) +export class ChangePlanDialogComponent implements OnInit { + @ViewChild(PaymentComponent) paymentComponent: PaymentComponent; + @ViewChild(TaxInfoComponent) taxComponent: TaxInfoComponent; + + @Input() acceptingSponsorship = false; + @Input() organizationId: string; + @Input() showFree = false; + @Input() showCancel = false; + selectedFile: File; + + @Input() + get productTier(): ProductTierType { + return this._productTier; + } + + set productTier(product: ProductTierType) { + this._productTier = product; + this.formGroup?.controls?.productTier?.setValue(product); + } + + private _productTier = ProductTierType.Free; + + @Input() + get plan(): PlanType { + return this._plan; + } + + set plan(plan: PlanType) { + this._plan = plan; + this.formGroup?.controls?.plan?.setValue(plan); + } + + private _plan = PlanType.Free; + @Input() providerId?: string; + @Output() onSuccess = new EventEmitter<OnSuccessArgs>(); + @Output() onCanceled = new EventEmitter<void>(); + @Output() onTrialBillingSuccess = new EventEmitter(); + + protected discountPercentage: number = 20; + protected discountPercentageFromSub: number; + protected loading = true; + protected planCards: PlanCard[]; + protected ResultType = ChangePlanDialogResultType; + + selfHosted = false; + productTypes = ProductTierType; + formPromise: Promise<string>; + singleOrgPolicyAppliesToActiveUser = false; + isInTrialFlow = false; + discount = 0; + + formGroup = this.formBuilder.group({ + name: [""], + billingEmail: ["", [Validators.email]], + businessOwned: [false], + premiumAccessAddon: [false], + additionalSeats: [0, [Validators.min(0), Validators.max(100000)]], + clientOwnerEmail: ["", [Validators.email]], + plan: [this.plan], + productTier: [this.productTier], + planInterval: [1], + }); + + planType: string; + selectedPlan: PlanResponse; + selectedInterval: number = 1; + planIntervals = PlanInterval; + passwordManagerPlans: PlanResponse[]; + organization: Organization; + sub: OrganizationSubscriptionResponse; + billing: BillingResponse; + currentPlanName: string; + showPayment: boolean = false; + totalOpened: boolean = false; + currentPlan: PlanResponse; + + private destroy$ = new Subject<void>(); + + constructor( + @Inject(DIALOG_DATA) private dialogParams: ChangePlanDialogParams, + private dialogRef: DialogRef<ChangePlanDialogResultType>, + private toastService: ToastService, + private apiService: ApiService, + private i18nService: I18nService, + private cryptoService: CryptoService, + private router: Router, + private syncService: SyncService, + private policyService: PolicyService, + private organizationService: OrganizationService, + private messagingService: MessagingService, + private formBuilder: FormBuilder, + private organizationApiService: OrganizationApiServiceAbstraction, + ) {} + + async ngOnInit(): Promise<void> { + if (this.dialogParams.organizationId) { + this.currentPlanName = this.resolvePlanName(this.dialogParams.productTierType); + this.sub = + this.dialogParams.subscription ?? + (await this.organizationApiService.getSubscription(this.dialogParams.organizationId)); + this.organizationId = this.dialogParams.organizationId; + this.currentPlan = this.sub?.plan; + this.selectedPlan = this.sub?.plan; + this.organization = await this.organizationService.get(this.organizationId); + this.billing = await this.organizationApiService.getBilling(this.organizationId); + } + + if (!this.selfHosted) { + const plans = await this.apiService.getPlans(); + this.passwordManagerPlans = plans.data.filter((plan) => !!plan.PasswordManager); + + if ( + this.productTier === ProductTierType.Enterprise || + this.productTier === ProductTierType.Teams + ) { + this.formGroup.controls.businessOwned.setValue(true); + } + } + + if (this.currentPlan && this.currentPlan.productTier !== ProductTierType.Enterprise) { + const upgradedPlan = this.passwordManagerPlans.find((plan) => + this.currentPlan.productTier === ProductTierType.Free + ? plan.type === PlanType.FamiliesAnnually + : plan.upgradeSortOrder == this.currentPlan.upgradeSortOrder + 1, + ); + + this.plan = upgradedPlan.type; + this.productTier = upgradedPlan.productTier; + } + this.upgradeFlowPrefillForm(); + + this.policyService + .policyAppliesToActiveUser$(PolicyType.SingleOrg) + .pipe(takeUntil(this.destroy$)) + .subscribe((policyAppliesToActiveUser) => { + this.singleOrgPolicyAppliesToActiveUser = policyAppliesToActiveUser; + }); + + if (!this.selfHosted) { + this.changedProduct(); + } + + this.planCards = [ + { + name: this.i18nService.t("planNameTeams"), + selected: true, + }, + { + name: this.i18nService.t("planNameEnterprise"), + selected: false, + }, + ]; + + this.formGroup + .get("planInterval") + .valueChanges.pipe(takeUntil(this.destroy$)) + .subscribe((value: number) => (this.selectedInterval = value)); + + this.discountPercentageFromSub = this.sub?.customerDiscount?.percentOff; + + this.setInitialPlanSelection(); + this.loading = false; + } + + setInitialPlanSelection() { + this.selectPlan(this.getPlanByType(ProductTierType.Enterprise)); + } + + getPlanByType(productTier: ProductTierType) { + return this.selectableProducts.find((product) => product.productTier === productTier); + } + + planTypeChanged() { + this.selectPlan(this.getPlanByType(ProductTierType.Enterprise)); + } + + protected getPlanIntervals() { + return [ + { + name: PlanInterval[PlanInterval.Annually], + value: PlanInterval.Annually, + }, + { + name: PlanInterval[PlanInterval.Monthly], + value: PlanInterval.Monthly, + }, + ]; + } + + protected getPlanCardContainerClasses(plan: PlanResponse, index: number) { + let cardState: PlanCardState; + + if (plan == this.selectedPlan) { + cardState = PlanCardState.Selected; + } else if ( + this.selectedInterval === PlanInterval.Monthly && + plan.productTier == ProductTierType.Families + ) { + cardState = PlanCardState.Disabled; + } else { + cardState = PlanCardState.NotSelected; + } + + switch (cardState) { + case PlanCardState.Selected: { + if (this.currentPlan.productTier === ProductTierType.Teams) { + return [ + "tw-group", + "tw-cursor-pointer", + "tw-block", + "tw-rounded", + "tw-w-1/2", + "tw-border", + "tw-border-solid", + "tw-border-primary-600", + "hover:tw-border-primary-700", + "focus:tw-border-2", + "focus:tw-border-primary-700", + "focus:tw-rounded-lg", + ]; + } else { + return [ + "tw-group", + "tw-cursor-pointer", + "tw-block", + "tw-rounded", + "tw-border", + "tw-border-solid", + "tw-border-primary-600", + "hover:tw-border-primary-700", + "focus:tw-border-2", + "focus:tw-border-primary-700", + "focus:tw-rounded-lg", + ]; + } + } + case PlanCardState.NotSelected: { + return [ + "tw-cursor-pointer", + "tw-block", + "tw-rounded", + "tw-border", + "tw-border-solid", + "tw-border-secondary-300", + "hover:tw-border-text-main", + "focus:tw-border-2", + "focus:tw-border-primary-700", + ]; + } + case PlanCardState.Disabled: { + return [ + "tw-cursor-not-allowed", + "tw-bg-secondary-100", + "tw-font-normal", + "tw-bg-blur", + "tw-text-muted", + "tw-block", + "tw-rounded", + "tw-border", + "tw-border-solid", + "tw-border-1", + "tw-border-secondary-300", + ]; + } + } + } + + protected selectPlan(plan: PlanResponse) { + if ( + this.selectedInterval === PlanInterval.Monthly && + plan.productTier == ProductTierType.Families + ) { + return; + } + this.selectedPlan = plan; + this.formGroup.patchValue({ productTier: plan.productTier }); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + + get upgradeRequiresPaymentMethod() { + return ( + this.organization?.productTierType === ProductTierType.Free && + !this.showFree && + !this.billing?.paymentSource + ); + } + + get selectedPlanInterval() { + return this.selectedPlan.isAnnual ? "year" : "month"; + } + + get selectableProducts() { + if (this.acceptingSponsorship) { + const familyPlan = this.passwordManagerPlans.find( + (plan) => plan.type === PlanType.FamiliesAnnually, + ); + this.discount = familyPlan.PasswordManager.basePrice; + return [familyPlan]; + } + + const businessOwnedIsChecked = this.formGroup.controls.businessOwned.value; + + const result = this.passwordManagerPlans.filter( + (plan) => + plan.type !== PlanType.Custom && + (!businessOwnedIsChecked || plan.canBeUsedByBusiness) && + (this.showFree || plan.productTier !== ProductTierType.Free) && + (plan.productTier === ProductTierType.Free || + plan.productTier === ProductTierType.TeamsStarter || + (this.selectedInterval === PlanInterval.Annually && plan.isAnnual) || + (this.selectedInterval === PlanInterval.Monthly && !plan.isAnnual)) && + (!this.currentPlan || this.currentPlan.upgradeSortOrder < plan.upgradeSortOrder) && + this.planIsEnabled(plan), + ); + + result.sort((planA, planB) => planA.displaySortOrder - planB.displaySortOrder); + + return result.reverse(); + } + + get selectablePlans() { + const selectedProductTierType = this.formGroup.controls.productTier.value; + const result = + this.passwordManagerPlans?.filter( + (plan) => plan.productTier === selectedProductTierType && this.planIsEnabled(plan), + ) || []; + + result.sort((planA, planB) => planA.displaySortOrder - planB.displaySortOrder); + return result; + } + + passwordManagerSeatTotal(plan: PlanResponse): number { + if (!plan.PasswordManager.hasAdditionalSeatsOption) { + return 0; + } + + const result = plan.PasswordManager.seatPrice * Math.abs(this.organization.seats || 0); + return result; + } + + get passwordManagerSubtotal() { + let subTotal = this.selectedPlan.PasswordManager.basePrice; + if (this.selectedPlan.PasswordManager.hasAdditionalSeatsOption) { + subTotal += this.passwordManagerSeatTotal(this.selectedPlan); + } + if (this.selectedPlan.PasswordManager.hasPremiumAccessOption) { + subTotal += this.selectedPlan.PasswordManager.premiumAccessOptionPrice; + } + return subTotal - this.discount; + } + + get taxCharges() { + return this.taxComponent != null && this.taxComponent.taxRate != null + ? (this.taxComponent.taxRate / 100) * this.passwordManagerSubtotal + : 0; + } + + get total() { + return this.passwordManagerSubtotal + this.taxCharges || 0; + } + + get teamsStarterPlanIsAvailable() { + return this.selectablePlans.some((plan) => plan.type === PlanType.TeamsStarter); + } + + changedProduct() { + const selectedPlan = this.selectablePlans[0]; + + this.setPlanType(selectedPlan.type); + this.handlePremiumAddonAccess(selectedPlan.PasswordManager.hasPremiumAccessOption); + this.handleAdditionalSeats(selectedPlan.PasswordManager.hasAdditionalSeatsOption); + } + + setPlanType(planType: PlanType) { + this.formGroup.controls.plan.setValue(planType); + } + + handlePremiumAddonAccess(hasPremiumAccessOption: boolean) { + this.formGroup.controls.premiumAccessAddon.setValue(!hasPremiumAccessOption); + } + + handleAdditionalSeats(selectedPlanHasAdditionalSeatsOption: boolean) { + if (!selectedPlanHasAdditionalSeatsOption) { + this.formGroup.controls.additionalSeats.setValue(0); + return; + } + + if (this.currentPlan && !this.currentPlan.PasswordManager.hasAdditionalSeatsOption) { + this.formGroup.controls.additionalSeats.setValue(this.currentPlan.PasswordManager.baseSeats); + return; + } + + if (this.organization) { + this.formGroup.controls.additionalSeats.setValue(this.organization.seats); + return; + } + + this.formGroup.controls.additionalSeats.setValue(1); + } + + changedCountry() { + if (this.paymentComponent && this.taxComponent) { + this.paymentComponent!.hideBank = this.taxComponent?.taxFormGroup?.value.country !== "US"; + // Bank Account payments are only available for US customers + if ( + this.paymentComponent.hideBank && + this.paymentComponent.method === PaymentMethodType.BankAccount + ) { + this.paymentComponent.method = PaymentMethodType.Card; + this.paymentComponent.changeMethod(); + } + } + } + + submit = async () => { + if (!this.taxComponent?.taxFormGroup.valid && this.taxComponent?.taxFormGroup.touched) { + this.taxComponent?.taxFormGroup.markAllAsTouched(); + return; + } + + const doSubmit = async (): Promise<string> => { + let orgId: string = null; + orgId = await this.updateOrganization(orgId); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("organizationUpgraded"), + }); + + await this.apiService.refreshIdentityToken(); + await this.syncService.fullSync(true); + + if (!this.acceptingSponsorship && !this.isInTrialFlow) { + // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this.router.navigate(["/organizations/" + orgId]); + } + + if (this.isInTrialFlow) { + this.onTrialBillingSuccess.emit({ + orgId: orgId, + subLabelText: this.billingSubLabelText(), + }); + } + + return orgId; + }; + + this.formPromise = doSubmit(); + const organizationId = await this.formPromise; + this.onSuccess.emit({ organizationId: organizationId }); + // TODO: No one actually listening to this message? + this.messagingService.send("organizationCreated", { organizationId }); + this.dialogRef.close(); + }; + + private async updateOrganization(orgId: string) { + const request = new OrganizationUpgradeRequest(); + if (this.selectedPlan.productTier !== ProductTierType.Families) { + request.additionalSeats = this.organization.seats; + } + request.premiumAccessAddon = + this.selectedPlan.PasswordManager.hasPremiumAccessOption && + this.formGroup.controls.premiumAccessAddon.value; + request.planType = this.selectedPlan.type; + if (this.showPayment) { + request.billingAddressCountry = this.taxComponent.taxFormGroup?.value.country; + request.billingAddressPostalCode = this.taxComponent.taxFormGroup?.value.postalCode; + } + + if (this.upgradeRequiresPaymentMethod || this.showPayment) { + const tokenResult = await this.paymentComponent.createPaymentToken(); + const paymentRequest = new PaymentRequest(); + paymentRequest.paymentToken = tokenResult[0]; + paymentRequest.paymentMethodType = tokenResult[1]; + paymentRequest.country = this.taxComponent.taxFormGroup?.value.country; + paymentRequest.postalCode = this.taxComponent.taxFormGroup?.value.postalCode; + await this.organizationApiService.updatePayment(this.organizationId, paymentRequest); + } + + // Backfill pub/priv key if necessary + if (!this.organization.hasPublicAndPrivateKeys) { + const orgShareKey = await this.cryptoService.getOrgKey(this.organizationId); + const orgKeys = await this.cryptoService.makeKeyPair(orgShareKey); + request.keys = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString); + } + + const result = await this.organizationApiService.upgrade(this.organizationId, request); + if (!result.success && result.paymentIntentClientSecret != null) { + await this.paymentComponent.handleStripeCardPayment(result.paymentIntentClientSecret, null); + } + return this.organizationId; + } + + private billingSubLabelText(): string { + const selectedPlan = this.selectedPlan; + const price = + selectedPlan.PasswordManager.basePrice === 0 + ? selectedPlan.PasswordManager.seatPrice + : selectedPlan.PasswordManager.basePrice; + let text = ""; + + if (selectedPlan.isAnnual) { + text += `${this.i18nService.t("annual")} ($${price}/${this.i18nService.t("yr")})`; + } else { + text += `${this.i18nService.t("monthly")} ($${price}/${this.i18nService.t("monthAbbr")})`; + } + + return text; + } + + private upgradeFlowPrefillForm() { + if (this.acceptingSponsorship) { + this.formGroup.controls.productTier.setValue(ProductTierType.Families); + this.changedProduct(); + return; + } + + if (this.currentPlan && this.currentPlan.productTier !== ProductTierType.Enterprise) { + const upgradedPlan = this.passwordManagerPlans.find((plan) => { + if (this.currentPlan.productTier === ProductTierType.Free) { + return plan.type === PlanType.FamiliesAnnually; + } + + if ( + this.currentPlan.productTier === ProductTierType.Families && + !this.teamsStarterPlanIsAvailable + ) { + return plan.type === PlanType.TeamsAnnually; + } + + return plan.upgradeSortOrder === this.currentPlan.upgradeSortOrder + 1; + }); + + this.plan = upgradedPlan.type; + this.productTier = upgradedPlan.productTier; + this.changedProduct(); + } + } + + private planIsEnabled(plan: PlanResponse) { + return !plan.disabled && !plan.legacyYear; + } + + toggleShowPayment() { + this.showPayment = true; + } + + toggleTotalOpened() { + this.totalOpened = !this.totalOpened; + } + + get paymentSourceClasses() { + if (this.billing.paymentSource == null) { + return []; + } + switch (this.billing.paymentSource.type) { + case PaymentMethodType.Card: + return ["bwi-credit-card"]; + case PaymentMethodType.BankAccount: + return ["bwi-bank"]; + case PaymentMethodType.Check: + return ["bwi-money"]; + case PaymentMethodType.PayPal: + return ["bwi-paypal text-primary"]; + default: + return []; + } + } + + resolvePlanName(productTier: ProductTierType) { + switch (productTier) { + case ProductTierType.Enterprise: + return this.i18nService.t("planNameEnterprise"); + case ProductTierType.Free: + return this.i18nService.t("planNameFree"); + case ProductTierType.Families: + return this.i18nService.t("planNameFamilies"); + case ProductTierType.Teams: + return this.i18nService.t("planNameTeams"); + } + } +} diff --git a/apps/web/src/app/billing/organizations/organization-billing.module.ts b/apps/web/src/app/billing/organizations/organization-billing.module.ts index a95efe32e47..5d9dd8cf5b5 100644 --- a/apps/web/src/app/billing/organizations/organization-billing.module.ts +++ b/apps/web/src/app/billing/organizations/organization-billing.module.ts @@ -7,6 +7,7 @@ import { BillingSharedModule } from "../shared"; import { AdjustSubscription } from "./adjust-subscription.component"; import { BillingSyncApiKeyComponent } from "./billing-sync-api-key.component"; import { BillingSyncKeyComponent } from "./billing-sync-key.component"; +import { ChangePlanDialogComponent } from "./change-plan-dialog.component"; import { ChangePlanComponent } from "./change-plan.component"; import { DownloadLicenceDialogComponent } from "./download-license.component"; import { OrgBillingHistoryViewComponent } from "./organization-billing-history-view.component"; @@ -40,6 +41,7 @@ import { SubscriptionStatusComponent } from "./subscription-status.component"; SecretsManagerSubscribeStandaloneComponent, SubscriptionHiddenComponent, SubscriptionStatusComponent, + ChangePlanDialogComponent, ], }) export class OrganizationBillingModule {} diff --git a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts index 20c38ec94fa..c5ed013b1e4 100644 --- a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts +++ b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts @@ -28,6 +28,7 @@ import { } from "../shared/offboarding-survey.component"; import { BillingSyncApiKeyComponent } from "./billing-sync-api-key.component"; +import { ChangePlanDialogResultType, openChangePlanDialog } from "./change-plan-dialog.component"; import { DownloadLicenceDialogComponent } from "./download-license.component"; import { ManageBilling } from "./icons/manage-billing.icon"; import { SecretsManagerSubscriptionOptions } from "./sm-adjust-subscription.component"; @@ -66,6 +67,10 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy FeatureFlag.EnableTimeThreshold, ); + protected EnableUpgradePasswordManagerSub$ = this.configService.getFeatureFlag$( + FeatureFlag.EnableUpgradePasswordManagerSub, + ); + constructor( private apiService: ApiService, private platformUtilsService: PlatformUtilsService, @@ -383,7 +388,26 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy }; async changePlan() { - this.showChangePlan = !this.showChangePlan; + const EnableUpgradePasswordManagerSub = await firstValueFrom( + this.EnableUpgradePasswordManagerSub$, + ); + if (EnableUpgradePasswordManagerSub) { + const reference = openChangePlanDialog(this.dialogService, { + data: { + organizationId: this.organizationId, + subscription: this.sub, + productTierType: this.userOrg.productTierType, + }, + }); + + const result = await lastValueFrom(reference.closed); + + if (result === ChangePlanDialogResultType.Submitted) { + await this.load(); + } + } else { + this.showChangePlan = !this.showChangePlan; + } } closeChangePlan() { diff --git a/apps/web/src/app/billing/shared/tax-info.component.ts b/apps/web/src/app/billing/shared/tax-info.component.ts index 289c4906e93..068bf8a18ce 100644 --- a/apps/web/src/app/billing/shared/tax-info.component.ts +++ b/apps/web/src/app/billing/shared/tax-info.component.ts @@ -394,7 +394,7 @@ export class TaxInfoComponent { }); // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.parent.parent.params.subscribe(async (params) => { + this.route.parent?.parent?.params.subscribe(async (params) => { this.organizationId = params.organizationId; if (this.organizationId) { try { diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 2be00bb8896..7af92a1e52d 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8738,5 +8738,92 @@ }, "purchasedSeatsRemoved": { "message": "purchased seats removed" + }, + "includesXMembers": { + "message": "for $COUNT$ member", + "placeholders": { + "count": { + "content": "$1", + "example": "5" + } + } + }, + "costPerMember": { + "message": "$COST$", + "placeholders": { + "cost": { + "content": "$1", + "example": "$3" + } + } + }, + "optionalOnPremHosting": { + "message": "Optional on-premises hosting" + }, + "upgradeFreeOrganization": { + "message": "Upgrade your $NAME$ organization ", + "placeholders": { + "name": { + "content": "$1", + "example": "Teams" + } + } + }, + "includeSsoAuthenticationMessage": { + "message": "SSO Authentication" + }, + "familiesPlanInvLimitReachedManageBilling": { + "message": "Families organizations may have up to $SEATCOUNT$ members. Upgrade to a paid plan to invite more members.", + "placeholders": { + "seatcount": { + "content": "$1", + "example": "6" + } + } + }, + "familiesPlanInvLimitReachedNoManageBilling": { + "message": "Families organizations may have up to $SEATCOUNT$ members. Contact your organization owner to upgrade.", + "placeholders": { + "seatcount": { + "content": "$1", + "example": "6" + } + } + }, + "upgradePlan": { + "message": "Upgrade your plan to invite more members and gain access to additional Bitwarden features" + }, + "upgradeDiscount": { + "message": "Save $AMOUNT$%", + "placeholders": { + "amount": { + "content": "$1", + "example": "2" + } + } + }, + "upgradeEnterpriseMessage": { + "message": "Advanced capabilities for larger businesses" + }, + "upgradeTeamsMessage": { + "message": "Businesses looking for powerful security" + }, + "teamsInviteMessage": { + "message": "Invite unlimited members" + }, + "accessToCreateGroups": { + "message": "Access to create groups" + }, + "syncGroupsAndUsersFromDirectory": { + "message": "Sync groups and users from a directory" + }, + "upgradeFamilyMessage": { + "message": "Share with families and friends" + }, + "accessToPremiumFeatures": { + "message": "Access to Premium features" + }, + "additionalStorageGbMessage": { + "message": "GB additional storage" } } diff --git a/libs/common/src/billing/enums/index.ts b/libs/common/src/billing/enums/index.ts index 3d89c7a5462..1a9f3f8219c 100644 --- a/libs/common/src/billing/enums/index.ts +++ b/libs/common/src/billing/enums/index.ts @@ -5,3 +5,4 @@ export * from "./transaction-type.enum"; export * from "./bitwarden-product-type.enum"; export * from "./product-tier-type.enum"; export * from "./product-type.enum"; +export * from "./plan-interval.enum"; diff --git a/libs/common/src/billing/enums/plan-interval.enum.ts b/libs/common/src/billing/enums/plan-interval.enum.ts new file mode 100644 index 00000000000..546336748cd --- /dev/null +++ b/libs/common/src/billing/enums/plan-interval.enum.ts @@ -0,0 +1,4 @@ +export enum PlanInterval { + Monthly = 0, + Annually = 1, +} diff --git a/libs/common/src/billing/enums/product-tier-type.enum.ts b/libs/common/src/billing/enums/product-tier-type.enum.ts index c40f913ec82..fadf57ccdc5 100644 --- a/libs/common/src/billing/enums/product-tier-type.enum.ts +++ b/libs/common/src/billing/enums/product-tier-type.enum.ts @@ -5,3 +5,11 @@ export enum ProductTierType { Enterprise = 3, TeamsStarter = 4, } + +export function isNotSelfUpgradable(productType: ProductTierType): boolean { + return ( + productType !== ProductTierType.Free && + productType !== ProductTierType.TeamsStarter && + productType !== ProductTierType.Families + ); +} diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index ce00640fa9b..08c8c35df3c 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -27,6 +27,7 @@ export enum FeatureFlag { AC2828_ProviderPortalMembersPage = "AC-2828_provider-portal-members-page", DeviceTrustLogging = "pm-8285-device-trust-logging", AuthenticatorTwoFactorToken = "authenticator-2fa-token", + EnableUpgradePasswordManagerSub = "AC-2708-upgrade-password-manager-sub", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -64,6 +65,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.AC2828_ProviderPortalMembersPage]: FALSE, [FeatureFlag.DeviceTrustLogging]: FALSE, [FeatureFlag.AuthenticatorTwoFactorToken]: FALSE, + [FeatureFlag.EnableUpgradePasswordManagerSub]: FALSE, } satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; From 83d03daafb9b6d0e78b459cfc72cf47be604ccec Mon Sep 17 00:00:00 2001 From: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Date: Tue, 30 Jul 2024 08:10:28 -0700 Subject: [PATCH 35/46] Bumped client version(s) (#10328) --- apps/web/package.json | 2 +- package-lock.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index b75d9eac4c2..7264a81d283 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2024.7.1", + "version": "2024.7.2", "scripts": { "build:oss": "webpack", "build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/package-lock.json b/package-lock.json index 49d59ba1986..ea39aef5043 100644 --- a/package-lock.json +++ b/package-lock.json @@ -249,7 +249,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2024.7.1" + "version": "2024.7.2" }, "libs/admin-console": { "name": "@bitwarden/admin-console", From 973aba1bf44249d405127b60ef92c3000d942520 Mon Sep 17 00:00:00 2001 From: Shane Melton <smelton@bitwarden.com> Date: Tue, 30 Jul 2024 08:14:17 -0700 Subject: [PATCH 36/46] [PM-8379] Fix Vault Popup Items service loading (#10324) * [PM-8379] Avoid fetching decrypted ciphers if no sync has completed * [PM-8379] Do not emit ciphers loading when applying filters --- .../vault-popup-items.service.spec.ts | 28 +++++++++---------- .../services/vault-popup-items.service.ts | 6 +++- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts index f6457b8db54..2ead93e5122 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-items.service.spec.ts @@ -1,11 +1,12 @@ import { TestBed } from "@angular/core/testing"; import { mock } from "jest-mock-extended"; -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject, firstValueFrom, timeout } from "rxjs"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { ProductTierType } from "@bitwarden/common/billing/enums"; +import { SyncService } from "@bitwarden/common/platform/sync"; import { ObservableTracker } from "@bitwarden/common/spec"; import { CipherId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -37,6 +38,7 @@ describe("VaultPopupItemsService", () => { const searchService = mock<SearchService>(); const collectionService = mock<CollectionService>(); const vaultAutofillServiceMock = mock<VaultPopupAutofillService>(); + const syncServiceMock = mock<SyncService>(); beforeEach(() => { allCiphers = cipherFactory(10); @@ -90,6 +92,8 @@ describe("VaultPopupItemsService", () => { organizationServiceMock.organizations$ = new BehaviorSubject([mockOrg]); collectionService.decryptedCollections$ = new BehaviorSubject(mockCollections); + syncServiceMock.getLastSync.mockResolvedValue(new Date()); + testBed = TestBed.configureTestingModule({ providers: [ { provide: CipherService, useValue: cipherServiceMock }, @@ -99,6 +103,7 @@ describe("VaultPopupItemsService", () => { { provide: VaultPopupListFiltersService, useValue: vaultPopupListFiltersServiceMock }, { provide: CollectionService, useValue: collectionService }, { provide: VaultPopupAutofillService, useValue: vaultAutofillServiceMock }, + { provide: SyncService, useValue: syncServiceMock }, ], }); @@ -155,6 +160,14 @@ describe("VaultPopupItemsService", () => { await expect(tracker.pauseUntilReceived(3)).rejects.toThrow("Timeout exceeded"); }); + it("should not emit cipher list if syncService.getLastSync returns null", async () => { + syncServiceMock.getLastSync.mockResolvedValue(null); + + const obs$ = service.autoFillCiphers$.pipe(timeout(50)); + + await expect(firstValueFrom(obs$)).rejects.toThrow("Timeout has occurred"); + }); + describe("autoFillCiphers$", () => { it("should return empty array if there is no current tab", (done) => { (vaultAutofillServiceMock.currentAutofillTab$ as BehaviorSubject<any>).next(null); @@ -394,19 +407,6 @@ describe("VaultPopupItemsService", () => { expect(tracked.emissions[1]).toBe(true); expect(tracked.emissions[2]).toBe(false); }); - - it("should cycle when filters are applied", async () => { - // Restart tracking - tracked = new ObservableTracker(service.loading$); - service.applyFilter("test"); - - await trackedCiphers.pauseUntilReceived(2); - - expect(tracked.emissions.length).toBe(3); - expect(tracked.emissions[0]).toBe(false); - expect(tracked.emissions[1]).toBe(true); - expect(tracked.emissions[2]).toBe(false); - }); }); describe("applyFilter", () => { diff --git a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts index eb1af2cf713..e78e289c75a 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts @@ -5,6 +5,7 @@ import { concatMap, distinctUntilChanged, distinctUntilKeyChanged, + filter, from, map, merge, @@ -21,6 +22,7 @@ import { import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { SyncService } from "@bitwarden/common/platform/sync"; import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; @@ -78,6 +80,8 @@ export class VaultPopupItemsService { ).pipe( runInsideAngular(inject(NgZone)), // Workaround to ensure cipher$ state provider emissions are run inside Angular tap(() => this._ciphersLoading$.next()), + switchMap(() => Utils.asyncToObservable(() => this.syncService.getLastSync())), + filter((lastSync) => lastSync !== null), // Only attempt to load ciphers if we performed a sync switchMap(() => Utils.asyncToObservable(() => this.cipherService.getAllDecrypted())), switchMap((ciphers) => combineLatest([ @@ -108,7 +112,6 @@ export class VaultPopupItemsService { this._searchText$, this.vaultPopupListFiltersService.filterFunction$, ]).pipe( - tap(() => this._ciphersLoading$.next()), map(([ciphers, searchText, filterFunction]): [CipherView[], string] => [ filterFunction(ciphers), searchText, @@ -236,6 +239,7 @@ export class VaultPopupItemsService { private searchService: SearchService, private collectionService: CollectionService, private vaultPopupAutofillService: VaultPopupAutofillService, + private syncService: SyncService, ) {} applyFilter(newSearchText: string) { From 81212deaad9b43f408040771b68b7600d87ed567 Mon Sep 17 00:00:00 2001 From: SmithThe4th <gsmith@bitwarden.com> Date: Tue, 30 Jul 2024 11:45:26 -0400 Subject: [PATCH 37/46] [PM-7306] Onboarding users to new UI (#10267) * Added translation keys * created simple dialog (cherry picked from commit c12257cf51ca5e0d773a160afb6860a8f5df66b7) * added announcement svg (cherry picked from commit 635103120b500103b93dc1a8cbefc34dd396445b) * removed announcement svg, moved svg to component, refactored component (cherry picked from commit 50db6aa40fd90d92afeeb60e919f98f268bd69b5) * renamed state definition (cherry picked from commit 4c3618c46ee5ffab7050fbc9f6d779ee59c0c26b) * created vault ui onboarding service (cherry picked from commit 19ba3c42656d4f891ba3635da06f3ff7656b6028) * added vault ui dialog to vault component (cherry picked from commit 56527c8e5eda7df2f222ceebdeba168e2f1ae278) * moved updating the state to vault component * updated the link and fixed minor issues * moved onboarding logic from component to service and fixed review comments --- apps/browser/src/_locales/en/messages.json | 6 ++ .../vault-ui-onboarding.component.ts | 73 +++++++++++++++ .../components/vault/vault-v2.component.ts | 8 +- .../services/vault-ui-onboarding.service.ts | 88 +++++++++++++++++++ .../src/platform/state/state-definitions.ts | 1 + 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts create mode 100644 apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 5ce5831e2e8..8b9ce12afd8 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -4014,5 +4014,11 @@ }, "itemLocation": { "message": "Item Location" + }, + "bitwardenNewLook": { + "message": "Bitwarden has a new look!" + }, + "bitwardenNewLookDesc": { + "message": "It's easier and more intuitive than ever to autofill and search from the Vault tab. Take a look around!" } } diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts new file mode 100644 index 00000000000..6324e4139d4 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts @@ -0,0 +1,73 @@ +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { + ButtonModule, + DialogModule, + DialogService, + IconModule, + svgIcon, +} from "@bitwarden/components"; + +const announcementIcon = svgIcon` +<svg xmlns="http://www.w3.org/2000/svg" width="86" height="74" fill="none"> + <g fill-rule="evenodd" clip-path="url(#a)" clip-rule="evenodd"> + <path class="tw-fill-text-headers" d="m17.477 51.274 2.472 17.441a3.779 3.779 0 0 0 4.583 3.154l1.497-.342a3.779 3.779 0 0 0 2.759-4.831L23.44 49.91l1.8-.573 5.348 16.784a5.668 5.668 0 0 1-4.138 7.247l-1.497.341a5.668 5.668 0 0 1-6.874-4.73l-2.473-17.44 1.871-.266Z"/> + <path class="tw-fill-info-600" d="m55.063 27.1-1.38.316-.211-.92 1.381-.316a3.306 3.306 0 0 1 3.96 2.486l1.052 4.605a3.306 3.306 0 0 1-2.487 3.96l-.92.21-.211-.92.92-.211a2.362 2.362 0 0 0 1.777-2.828l-1.052-4.605a2.362 2.362 0 0 0-2.829-1.777Z"/> + <path class="tw-fill-text-headers" d="M49.79 12.5a.18.18 0 0 0-.272-.11L21.855 29.438a.181.181 0 0 0-.058.055l-.208.323-10.947 2.5a.457.457 0 0 0-.139.064.664.664 0 0 0-.15.135.343.343 0 0 0-.06.095l.499 2.182-4.36.996c-1.873.428-3.086 2.465-2.64 4.417l1.5 6.566c.446 1.951 2.423 3.26 4.296 2.832l4.36-.996.499 2.182c.012.012.04.034.095.06a.658.658 0 0 0 .194.055c.07.009.122.004.152-.003l10.947-2.501.328.2a.18.18 0 0 0 .075.025l32.324 3.344a.18.18 0 0 0 .196-.218L49.79 12.5Zm-1.263-1.72a2.07 2.07 0 0 1 3.104 1.299L60.6 51.332a2.07 2.07 0 0 1-2.233 2.517l-32.323-3.343a2.072 2.072 0 0 1-.474-.106l-10.26 2.344a2.474 2.474 0 0 1-1.571-.184c-.463-.217-.973-.643-1.127-1.32l-.085-.37-2.518.576c-2.975.68-5.9-1.37-6.559-4.253l-1.5-6.566c-.659-2.883 1.086-6 4.061-6.68l2.518-.575-.084-.37c-.155-.677.12-1.282.442-1.678.325-.4.803-.727 1.334-.848l10.262-2.345c.113-.113.24-.214.38-.3l27.664-17.05Z"/> + <path class="tw-fill-info-600" d="m10.792 34.793 3.156 13.814-.92.21L9.87 35.004l.921-.21ZM21.59 29.817l4.246 18.578-.508.12-.512.118L20.68 30.02l.91-.203Z"/> + <path class="tw-fill-text-headers" d="M64.287.59A.945.945 0 0 1 65.58.248c8.784 5.11 15.628 14.039 18.166 25.145 2.537 11.105.25 22.12-5.443 30.538a.945.945 0 0 1-1.565-1.059c5.398-7.98 7.587-18.46 5.166-29.058C79.48 15.215 72.958 6.726 64.629 1.882A.945.945 0 0 1 64.287.59Z"/> + <path class="tw-fill-info-600" d="M61.6 6.385a.472.472 0 0 1 .643-.18c7.245 4.067 12.949 11.44 15.055 20.66s.171 18.338-4.588 25.149a.472.472 0 0 1-.774-.542c4.603-6.587 6.49-15.431 4.441-24.397-2.048-8.965-7.59-16.113-14.596-20.047a.472.472 0 0 1-.18-.643Z"/> + <path class="tw-fill-text-headers" d="M57.804 11.193a.472.472 0 0 1 .604-.285c6.11 2.186 11.426 8.739 13.364 17.22 1.938 8.48-.006 16.693-4.56 21.315a.472.472 0 1 1-.672-.663c4.27-4.335 6.197-12.187 4.311-20.442-1.886-8.254-7.032-14.49-12.761-16.54a.472.472 0 0 1-.286-.605Z"/> + </g> + <defs> + <clipPath id="a"> + <path fill="#fff" d="M0 0h86v74H0z"/> + </clipPath> + </defs> +</svg> +`; + +@Component({ + standalone: true, + selector: "app-vault-ui-onboarding", + template: ` + <bit-simple-dialog> + <div bitDialogIcon> + <bit-icon [icon]="icon"></bit-icon> + </div> + <span bitDialogTitle> + {{ "bitwardenNewLook" | i18n }} + </span> + <span bitDialogContent> + {{ "bitwardenNewLookDesc" | i18n }} + </span> + + <ng-container bitDialogFooter> + <a bitButton buttonType="primary" bitDialogClose (click)="navigateToLink()"> + {{ "learnMore" | i18n }} + <i class="bwi bwi-external-link bwi-fw" aria-hidden="true"></i> + </a> + <button bitButton type="button" buttonType="secondary" bitDialogClose> + {{ "close" | i18n }} + </button> + </ng-container> + </bit-simple-dialog> + `, + imports: [CommonModule, DialogModule, ButtonModule, JslibModule, IconModule], +}) +export class VaultUiOnboardingComponent { + icon = announcementIcon; + + static open(dialogService: DialogService) { + return dialogService.open<boolean>(VaultUiOnboardingComponent); + } + + navigateToLink = async () => { + window.open( + "https://bitwarden.com/blog/bringing-intuitive-workflows-and-visual-updates-to-the-bitwarden-browser/", + "_blank", + ); + }; +} diff --git a/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts index 0e256476619..11331277a9c 100644 --- a/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts @@ -15,6 +15,7 @@ import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-he import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page.component"; import { VaultPopupItemsService } from "../../services/vault-popup-items.service"; import { VaultPopupListFiltersService } from "../../services/vault-popup-list-filters.service"; +import { VaultUiOnboardingService } from "../../services/vault-ui-onboarding.service"; import { AutofillVaultListItemsComponent, VaultListItemsContainerComponent } from "../vault-v2"; import { NewItemDropdownV2Component, @@ -49,9 +50,11 @@ enum VaultState { VaultV2SearchComponent, NewItemDropdownV2Component, ], + providers: [VaultUiOnboardingService], }) export class VaultV2Component implements OnInit, OnDestroy { cipherType = CipherType; + protected favoriteCiphers$ = this.vaultPopupItemsService.favoriteCiphers$; protected remainingCiphers$ = this.vaultPopupItemsService.remainingCiphers$; protected loading$ = this.vaultPopupItemsService.loading$; @@ -79,6 +82,7 @@ export class VaultV2Component implements OnInit, OnDestroy { constructor( private vaultPopupItemsService: VaultPopupItemsService, private vaultPopupListFiltersService: VaultPopupListFiltersService, + private vaultUiOnboardingService: VaultUiOnboardingService, ) { combineLatest([ this.vaultPopupItemsService.emptyVault$, @@ -104,7 +108,9 @@ export class VaultV2Component implements OnInit, OnDestroy { }); } - ngOnInit(): void {} + async ngOnInit() { + await this.vaultUiOnboardingService.showOnboardingDialog(); + } ngOnDestroy(): void {} } diff --git a/apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts b/apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts new file mode 100644 index 00000000000..151f8517d57 --- /dev/null +++ b/apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts @@ -0,0 +1,88 @@ +import { Injectable } from "@angular/core"; +import { firstValueFrom, map } from "rxjs"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { + GlobalState, + KeyDefinition, + StateProvider, + VAULT_BROWSER_UI_ONBOARDING, +} from "@bitwarden/common/platform/state"; +import { DialogService } from "@bitwarden/components"; + +import { VaultUiOnboardingComponent } from "../components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component"; + +// Key definition for the Vault UI onboarding state. +// This key is used to store the state of the new UI information dialog. +export const GLOBAL_VAULT_UI_ONBOARDING = new KeyDefinition<boolean>( + VAULT_BROWSER_UI_ONBOARDING, + "dialogState", + { + deserializer: (obj) => obj, + }, +); + +@Injectable() +export class VaultUiOnboardingService { + // TODO: Update this date to the release date of the new Browser UI + private onboardingUiReleaseDate = new Date("2024-07-25"); + + private vaultUiOnboardingState: GlobalState<boolean> = this.stateProvider.getGlobal( + GLOBAL_VAULT_UI_ONBOARDING, + ); + + private readonly vaultUiOnboardingState$ = this.vaultUiOnboardingState.state$.pipe( + map((x) => x ?? false), + ); + + constructor( + private stateProvider: StateProvider, + private dialogService: DialogService, + private apiService: ApiService, + ) {} + + /** + * Checks whether the onboarding dialog should be shown and opens it if necessary. + * The dialog is shown if the user has not previously viewed it and is not a new account. + */ + async showOnboardingDialog(): Promise<void> { + const hasViewedDialog = await this.getVaultUiOnboardingState(); + + if (!hasViewedDialog && !(await this.isNewAccount())) { + await this.openVaultUiOnboardingDialog(); + } + } + + private async openVaultUiOnboardingDialog(): Promise<boolean> { + const dialogRef = VaultUiOnboardingComponent.open(this.dialogService); + + const result = firstValueFrom(dialogRef.closed); + + // Update the onboarding state when the dialog is closed + await this.setVaultUiOnboardingState(true); + + return result; + } + + private async isNewAccount(): Promise<boolean> { + const userProfile = await this.apiService.getProfile(); + const profileCreationDate = new Date(userProfile.creationDate); + return profileCreationDate > this.onboardingUiReleaseDate; + } + + /** + * Updates and saves the state indicating whether the user has viewed + * the new UI onboarding information dialog. + */ + private async setVaultUiOnboardingState(value: boolean): Promise<void> { + await this.vaultUiOnboardingState.update(() => value); + } + + /** + * Retrieves the current state indicating whether the user has viewed + * the new UI onboarding information dialog.s + */ + private async getVaultUiOnboardingState(): Promise<boolean> { + return await firstValueFrom(this.vaultUiOnboardingState$); + } +} diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index 0b55e7be77c..fb00942f3e3 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -165,3 +165,4 @@ export const PREMIUM_BANNER_DISK_LOCAL = new StateDefinition("premiumBannerRepro web: "disk-local", }); export const BANNERS_DISMISSED_DISK = new StateDefinition("bannersDismissed", "disk"); +export const VAULT_BROWSER_UI_ONBOARDING = new StateDefinition("vaultBrowserUiOnboarding", "disk"); From 84ee01caeea3b122b2d54b55d73725c2df9d1d93 Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Tue, 30 Jul 2024 10:55:09 -0500 Subject: [PATCH 38/46] [PM-7103] Identity View (#10240) * make headings of v2 view component lowercase * initial add of view identity sections * adding identification fields * add contact information section * add copy ability to all identity fields * add visibility toggle for passport and ssn * add testids for all identity fields * add test-ids to visibility toggles * refactor visibility methods to be called in `ngOnInit` rather than on each render * replace `disabled` with `readonly` --- apps/browser/src/_locales/en/messages.json | 15 ++ .../cipher-view/cipher-view.component.html | 4 + .../src/cipher-view/cipher-view.component.ts | 2 + .../view-identity-sections.component.html | 161 ++++++++++++++ .../view-identity-sections.component.spec.ts | 200 ++++++++++++++++++ .../view-identity-sections.component.ts | 72 +++++++ 6 files changed, 454 insertions(+) create mode 100644 libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.html create mode 100644 libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts create mode 100644 libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 8b9ce12afd8..432479aa80a 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -116,6 +116,21 @@ "copySecurityCode": { "message": "Copy security code" }, + "copyName": { + "message": "Copy name" + }, + "copyCompany": { + "message": "Copy company" + }, + "copySSN": { + "message": "Copy Social Security number" + }, + "copyPassportNumber": { + "message": "Copy passport number" + }, + "copyLicenseNumber": { + "message": "Copy license number" + }, "autoFill": { "message": "Autofill" }, diff --git a/libs/vault/src/cipher-view/cipher-view.component.html b/libs/vault/src/cipher-view/cipher-view.component.html index 5ef7f12341c..1463cbd7315 100644 --- a/libs/vault/src/cipher-view/cipher-view.component.html +++ b/libs/vault/src/cipher-view/cipher-view.component.html @@ -8,6 +8,10 @@ > </app-item-details-v2> + <!-- IDENTITY SECTIONS --> + <app-view-identity-sections *ngIf="cipher.identity" [cipher]="cipher"> + </app-view-identity-sections> + <!-- ADDITIONAL OPTIONS --> <ng-container *ngIf="cipher.notes"> <app-additional-options [notes]="cipher.notes"> </app-additional-options> diff --git a/libs/vault/src/cipher-view/cipher-view.component.ts b/libs/vault/src/cipher-view/cipher-view.component.ts index 6e208d6f280..7e72424e1f0 100644 --- a/libs/vault/src/cipher-view/cipher-view.component.ts +++ b/libs/vault/src/cipher-view/cipher-view.component.ts @@ -22,6 +22,7 @@ import { AttachmentsV2ViewComponent } from "./attachments/attachments-v2-view.co import { CustomFieldV2Component } from "./custom-fields/custom-fields-v2.component"; import { ItemDetailsV2Component } from "./item-details/item-details-v2.component"; import { ItemHistoryV2Component } from "./item-history/item-history-v2.component"; +import { ViewIdentitySectionsComponent } from "./view-identity-sections/view-identity-sections.component"; @Component({ selector: "app-cipher-view", @@ -39,6 +40,7 @@ import { ItemHistoryV2Component } from "./item-history/item-history-v2.component AttachmentsV2ViewComponent, ItemHistoryV2Component, CustomFieldV2Component, + ViewIdentitySectionsComponent, ], }) export class CipherViewComponent implements OnInit { diff --git a/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.html b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.html new file mode 100644 index 00000000000..742f3a5efe3 --- /dev/null +++ b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.html @@ -0,0 +1,161 @@ +<bit-section *ngIf="showPersonalDetails"> + <bit-section-header> + <h2 bitTypography="h6">{{ "personalDetails" | i18n }}</h2> + </bit-section-header> + + <bit-card> + <bit-form-field *ngIf="cipher.identity.fullName"> + <bit-label>{{ "name" | i18n }}</bit-label> + <input bitInput [value]="cipher.identity.fullName" readonly data-testid="name" /> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyName' | i18n" + [appCopyClick]="cipher.identity.fullName" + showToast + ></button> + </bit-form-field> + <bit-form-field *ngIf="cipher.identity.username"> + <bit-label>{{ "username" | i18n }}</bit-label> + <input bitInput [value]="cipher.identity.username" readonly data-testid="username" /> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyUsername' | i18n" + [appCopyClick]="cipher.identity.username" + showToast + ></button> + </bit-form-field> + <bit-form-field *ngIf="cipher.identity.company"> + <bit-label>{{ "company" | i18n }}</bit-label> + <input bitInput [value]="cipher.identity.company" readonly data-testid="company" /> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyCompany' | i18n" + [appCopyClick]="cipher.identity.company" + showToast + ></button> + </bit-form-field> + </bit-card> +</bit-section> + +<bit-section *ngIf="showIdentificationDetails"> + <bit-section-header> + <h2 bitTypography="h6">{{ "identification" | i18n }}</h2> + </bit-section-header> + + <bit-card> + <bit-form-field *ngIf="cipher.identity.ssn"> + <bit-label>{{ "ssn" | i18n }}</bit-label> + <input bitInput type="password" [value]="cipher.identity.ssn" readonly data-testid="ssn" /> + <button + type="button" + bitIconButton + bitSuffix + bitPasswordInputToggle + data-testid="ssn-toggle" + ></button> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copySSN' | i18n" + [appCopyClick]="cipher.identity.ssn" + showToast + ></button> + </bit-form-field> + <bit-form-field *ngIf="cipher.identity.passportNumber"> + <bit-label>{{ "passportNumber" | i18n }}</bit-label> + <input + bitInput + type="password" + [value]="cipher.identity.passportNumber" + readonly + data-testid="passport" + /> + <button + type="button" + bitIconButton + bitSuffix + bitPasswordInputToggle + data-testid="passport-toggle" + ></button> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyPassportNumber' | i18n" + [appCopyClick]="cipher.identity.passportNumber" + showToast + ></button> + </bit-form-field> + <bit-form-field *ngIf="cipher.identity.licenseNumber"> + <bit-label>{{ "licenseNumber" | i18n }}</bit-label> + <input bitInput [value]="cipher.identity.licenseNumber" readonly data-testid="license" /> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyLicenseNumber' | i18n" + [appCopyClick]="cipher.identity.licenseNumber" + showToast + ></button> + </bit-form-field> + </bit-card> +</bit-section> + +<bit-section *ngIf="showContactDetails"> + <bit-section-header> + <h2 bitTypography="h6">{{ "contactInfo" | i18n }}</h2> + </bit-section-header> + + <bit-card> + <bit-form-field *ngIf="cipher.identity.email"> + <bit-label>{{ "email" | i18n }}</bit-label> + <input bitInput [value]="cipher.identity.email" readonly data-testid="email" /> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyEmail' | i18n" + [appCopyClick]="cipher.identity.email" + showToast + ></button> + </bit-form-field> + <bit-form-field *ngIf="cipher.identity.phone"> + <bit-label>{{ "phone" | i18n }}</bit-label> + <input bitInput [value]="cipher.identity.phone" readonly data-testid="phone" /> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyPhone' | i18n" + [appCopyClick]="cipher.identity.phone" + showToast + ></button> + </bit-form-field> + <bit-form-field *ngIf="addressFields"> + <bit-label>{{ "address" | i18n }}</bit-label> + <textarea + bitInput + class="tw-resize-none" + [value]="addressFields" + [rows]="addressRows" + readonly + data-testid="address" + ></textarea> + <button + type="button" + bitIconButton="bwi-clone" + bitSuffix + [appA11yTitle]="'copyAddress' | i18n" + [appCopyClick]="addressFields" + showToast + ></button> + </bit-form-field> + </bit-card> +</bit-section> diff --git a/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts new file mode 100644 index 00000000000..4c84b2852a8 --- /dev/null +++ b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.spec.ts @@ -0,0 +1,200 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { mock } from "jest-mock-extended"; + +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view"; +import { SectionHeaderComponent } from "@bitwarden/components"; + +import { BitInputDirective } from "../../../../components/src/input/input.directive"; + +import { ViewIdentitySectionsComponent } from "./view-identity-sections.component"; + +describe("ViewIdentitySectionsComponent", () => { + let component: ViewIdentitySectionsComponent; + let fixture: ComponentFixture<ViewIdentitySectionsComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ViewIdentitySectionsComponent], + providers: [ + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: PlatformUtilsService, useValue: mock<PlatformUtilsService>() }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewIdentitySectionsComponent); + component = fixture.componentInstance; + component.cipher = { identity: new IdentityView() } as CipherView; + fixture.detectChanges(); + }); + + describe("personal details", () => { + it("dynamically shows the section", () => { + let personalDetailSection = fixture.debugElement.query(By.directive(SectionHeaderComponent)); + + expect(personalDetailSection).toBeNull(); + + component.cipher = { + identity: { + fullName: "Mr Ron Burgundy", + }, + } as CipherView; + + component.ngOnInit(); + fixture.detectChanges(); + + personalDetailSection = fixture.debugElement.query(By.directive(SectionHeaderComponent)); + + expect(personalDetailSection).not.toBeNull(); + expect(personalDetailSection.nativeElement.textContent).toBe("personalDetails"); + }); + + it("populates personal detail fields", () => { + component.cipher = { + identity: { + fullName: "Mr Ron Burgundy", + company: "Channel 4 News", + username: "ron.burgundy", + }, + } as CipherView; + + component.ngOnInit(); + fixture.detectChanges(); + + const fields = fixture.debugElement.queryAll(By.directive(BitInputDirective)); + + expect(fields[0].nativeElement.value).toBe("Mr Ron Burgundy"); + expect(fields[1].nativeElement.value).toBe("ron.burgundy"); + expect(fields[2].nativeElement.value).toBe("Channel 4 News"); + }); + }); + + describe("identification details", () => { + it("dynamically shows the section", () => { + let identificationDetailSection = fixture.debugElement.query( + By.directive(SectionHeaderComponent), + ); + + expect(identificationDetailSection).toBeNull(); + + component.cipher = { + identity: { + ssn: "123-45-6789", + }, + } as CipherView; + + component.ngOnInit(); + fixture.detectChanges(); + + identificationDetailSection = fixture.debugElement.query( + By.directive(SectionHeaderComponent), + ); + + expect(identificationDetailSection).not.toBeNull(); + expect(identificationDetailSection.nativeElement.textContent).toBe("identification"); + }); + + it("populates identification detail fields", () => { + component.cipher = { + identity: { + ssn: "123-45-6789", + passportNumber: "998-765-4321", + licenseNumber: "404-HTTP", + }, + } as CipherView; + + component.ngOnInit(); + fixture.detectChanges(); + + const fields = fixture.debugElement.queryAll(By.directive(BitInputDirective)); + + expect(fields[0].nativeElement.value).toBe("123-45-6789"); + expect(fields[1].nativeElement.value).toBe("998-765-4321"); + expect(fields[2].nativeElement.value).toBe("404-HTTP"); + }); + }); + + describe("contact details", () => { + it("dynamically shows the section", () => { + let contactDetailSection = fixture.debugElement.query(By.directive(SectionHeaderComponent)); + + expect(contactDetailSection).toBeNull(); + + component.cipher = { + identity: { + email: "jack@gnn.com", + }, + } as CipherView; + + component.ngOnInit(); + fixture.detectChanges(); + + contactDetailSection = fixture.debugElement.query(By.directive(SectionHeaderComponent)); + + expect(contactDetailSection).not.toBeNull(); + expect(contactDetailSection.nativeElement.textContent).toBe("contactInfo"); + }); + + it("populates contact detail fields", () => { + component.cipher = { + identity: { + email: "jack@gnn.com", + phone: "608-867-5309", + address1: "2920 Zoo Dr", + address2: "Exhibit 200", + address3: "Tree 7", + fullAddressPart2: "San Diego, CA 92101", + country: "USA", + }, + } as CipherView; + + component.ngOnInit(); + fixture.detectChanges(); + + const fields = fixture.debugElement.queryAll(By.directive(BitInputDirective)); + + expect(fields[0].nativeElement.value).toBe("jack@gnn.com"); + expect(fields[1].nativeElement.value).toBe("608-867-5309"); + expect(fields[2].nativeElement.value).toBe( + "2920 Zoo Dr\nExhibit 200\nTree 7\nSan Diego, CA 92101\nUSA", + ); + }); + + it('returns the number of "rows" that should be assigned to the address textarea', () => { + component.cipher = { + identity: { + address1: "2920 Zoo Dr", + address2: "Exhibit 200", + address3: "Tree 7", + fullAddressPart2: "San Diego, CA 92101", + country: "USA", + }, + } as CipherView; + + component.ngOnInit(); + fixture.detectChanges(); + + let textarea = fixture.debugElement.query(By.css("textarea")); + + expect(textarea.nativeElement.rows).toBe(5); + + component.cipher = { + identity: { + address1: "2920 Zoo Dr", + country: "USA", + }, + } as CipherView; + + fixture.detectChanges(); + + textarea = fixture.debugElement.query(By.css("textarea")); + + expect(textarea.nativeElement.rows).toBe(2); + }); + }); +}); diff --git a/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.ts b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.ts new file mode 100644 index 00000000000..0fd2c292952 --- /dev/null +++ b/libs/vault/src/cipher-view/view-identity-sections/view-identity-sections.component.ts @@ -0,0 +1,72 @@ +import { NgIf } from "@angular/common"; +import { Component, Input, OnInit } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { + CardComponent, + FormFieldModule, + IconButtonModule, + SectionComponent, + SectionHeaderComponent, + TypographyModule, +} from "@bitwarden/components"; + +@Component({ + standalone: true, + selector: "app-view-identity-sections", + templateUrl: "./view-identity-sections.component.html", + imports: [ + NgIf, + JslibModule, + CardComponent, + SectionComponent, + SectionHeaderComponent, + TypographyModule, + FormFieldModule, + IconButtonModule, + ], +}) +export class ViewIdentitySectionsComponent implements OnInit { + @Input() cipher: CipherView; + + showPersonalDetails: boolean; + showIdentificationDetails: boolean; + showContactDetails: boolean; + + ngOnInit(): void { + this.showPersonalDetails = this.hasPersonalDetails(); + this.showIdentificationDetails = this.hasIdentificationDetails(); + this.showContactDetails = this.hasContactDetails(); + } + + /** Returns all populated address fields */ + get addressFields(): string { + const { address1, address2, address3, fullAddressPart2, country } = this.cipher.identity; + return [address1, address2, address3, fullAddressPart2, country].filter(Boolean).join("\n"); + } + + /** Returns the number of "rows" that should be assigned to the address textarea */ + get addressRows(): number { + return this.addressFields.split("\n").length; + } + + /** Returns true when any of the "personal detail" attributes are populated */ + private hasPersonalDetails(): boolean { + const { username, company, fullName } = this.cipher.identity; + return Boolean(fullName || username || company); + } + + /** Returns true when any of the "identification detail" attributes are populated */ + private hasIdentificationDetails(): boolean { + const { ssn, passportNumber, licenseNumber } = this.cipher.identity; + return Boolean(ssn || passportNumber || licenseNumber); + } + + /** Returns true when any of the "contact detail" attributes are populated */ + private hasContactDetails(): boolean { + const { email, phone } = this.cipher.identity; + + return Boolean(email || phone || this.addressFields); + } +} From d915bd8c86b32bb0bfc13cf389a76965b4d1d85a Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:41:10 -0400 Subject: [PATCH 39/46] Auth/PM-10069 - Unauthenticated UI Extension Refresh Swap Utility (#10327) * PM-3515 - Lock component - remove isUnlocked check on lock comp load b/c lock guard should cover all cases with its existing logic for all clients. * PM-9685 - Add new feature flag * PM-10069 - ExtensionRefreshRouteUtils - Add unauthExtensionRefreshSwap helper * Restore lock component --- .../popup/extension-refresh-route-utils.ts | 24 +++++++++++++++++++ libs/common/src/enums/feature-flag.enum.ts | 2 ++ 2 files changed, 26 insertions(+) diff --git a/apps/browser/src/popup/extension-refresh-route-utils.ts b/apps/browser/src/popup/extension-refresh-route-utils.ts index 3c2ca33f86e..6960b650fa7 100644 --- a/apps/browser/src/popup/extension-refresh-route-utils.ts +++ b/apps/browser/src/popup/extension-refresh-route-utils.ts @@ -27,6 +27,30 @@ export function extensionRefreshSwap( ); } +/** + * Helper function to swap between two components based on the UnauthenticatedExtensionUIRefresh feature flag. + * We need this because the auth teams's authenticated UI will be refreshed as part of the MVP but the + * unauthenticated UIs will not necessarily make the cut. + * @param defaultComponent - The current non-refreshed component to render. + * @param refreshedComponent - The new refreshed component to render. + * @param options - The shared route options to apply to both components. + */ +export function unauthExtensionRefreshSwap( + defaultComponent: Type<any>, + refreshedComponent: Type<any>, + options: Route, +): Routes { + return componentRouteSwap( + defaultComponent, + refreshedComponent, + async () => { + const configService = inject(ConfigService); + return configService.getFeatureFlag(FeatureFlag.UnauthenticatedExtensionUIRefresh); + }, + options, + ); +} + /** * Helper function to redirect to a new URL based on the ExtensionRefresh feature flag. * @param redirectUrl - The URL to redirect to if the ExtensionRefresh flag is enabled. diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 08c8c35df3c..f077e5a554f 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -27,6 +27,7 @@ export enum FeatureFlag { AC2828_ProviderPortalMembersPage = "AC-2828_provider-portal-members-page", DeviceTrustLogging = "pm-8285-device-trust-logging", AuthenticatorTwoFactorToken = "authenticator-2fa-token", + UnauthenticatedExtensionUIRefresh = "unauth-ui-refresh", EnableUpgradePasswordManagerSub = "AC-2708-upgrade-password-manager-sub", } @@ -65,6 +66,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.AC2828_ProviderPortalMembersPage]: FALSE, [FeatureFlag.DeviceTrustLogging]: FALSE, [FeatureFlag.AuthenticatorTwoFactorToken]: FALSE, + [FeatureFlag.UnauthenticatedExtensionUIRefresh]: FALSE, [FeatureFlag.EnableUpgradePasswordManagerSub]: FALSE, } satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>; From 18ef51449f4a31b6d3937f469b0ab117be0f9b9a Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:48:51 -0500 Subject: [PATCH 40/46] [PM-8307] AnonLayout Design Changes (#10166) * update logo, padding, and add hideFooter property and hideLogo input * typography and icon adjustments * add story with hidden logo input * handle updating the icon * update storybook docs * update border radius * update icon colors to use tw classes * update storybook docs * handle default icon * make hideFooter an input * update icon sizing * update icon sizing --- .../anon-layout/anon-layout.component.html | 24 ++++++----- .../anon-layout/anon-layout.component.ts | 40 +++++++++++++++---- .../anon-layout/anon-layout.stories.ts | 35 +++++++++++++++- .../angular/icons/bitwarden-shield.icon.ts | 13 ++++++ libs/auth/src/angular/icons/index.ts | 1 + libs/auth/src/angular/icons/lock.icon.ts | 14 ++++++- 6 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 libs/auth/src/angular/icons/bitwarden-shield.icon.ts diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.html b/libs/auth/src/angular/anon-layout/anon-layout.component.html index d6e80c27709..3af22a704fd 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.html +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.html @@ -1,35 +1,37 @@ <main - class="tw-flex tw-min-h-screen tw-w-full tw-mx-auto tw-flex-col tw-gap-9 tw-bg-background-alt tw-px-4 tw-pb-4 tw-pt-14 tw-text-main" + class="tw-flex tw-min-h-screen tw-w-full tw-mx-auto tw-flex-col tw-gap-7 tw-bg-background-alt tw-px-8 tw-pb-4 tw-pt-8 tw-text-main" > + <bit-icon *ngIf="!hideLogo" [icon]="logo" class="tw-max-w-36"></bit-icon> + <div class="tw-text-center"> - <div class="tw-px-8"> - <div *ngIf="icon" class="tw-mb-8"> - <bit-icon [icon]="icon"></bit-icon> - </div> - <bit-icon [icon]="logo" class="tw-mx-auto tw-block tw-max-w-72 sm:tw-max-w-xs"></bit-icon> + <div class="tw-mx-auto tw-max-w-28 sm:tw-max-w-32"> + <bit-icon [icon]="icon"></bit-icon> </div> - <h1 *ngIf="title" bitTypography="h3" class="tw-mt-8 sm:tw-text-2xl"> + + <h1 *ngIf="title" bitTypography="h3" class="tw-mt-2 sm:tw-text-2xl"> {{ title }} </h1> - <p *ngIf="subtitle" bitTypography="body1">{{ subtitle }}</p> + <div *ngIf="subtitle" class="tw-text-sm sm:tw-text-base">{{ subtitle }}</div> </div> + <div class="tw-mb-auto tw-w-full tw-max-w-md tw-mx-auto tw-flex tw-flex-col tw-items-center sm:tw-min-w-[28rem]" [ngClass]="{ 'tw-max-w-md': maxWidth === 'md', 'tw-max-w-3xl': maxWidth === '3xl' }" > <div - class="tw-rounded-xl tw-mb-9 tw-mx-auto tw-w-full sm:tw-bg-background sm:tw-border sm:tw-border-solid sm:tw-border-secondary-300 sm:tw-p-8" + class="tw-rounded-2xl tw-mb-9 tw-mx-auto tw-w-full sm:tw-bg-background sm:tw-border sm:tw-border-solid sm:tw-border-secondary-300 sm:tw-p-8" > <ng-content></ng-content> </div> <ng-content select="[slot=secondary]"></ng-content> </div> - <footer class="tw-text-center"> + + <footer *ngIf="!hideFooter" class="tw-text-center"> <div *ngIf="showReadonlyHostname">{{ "accessing" | i18n }} {{ hostname }}</div> <ng-container *ngIf="!showReadonlyHostname"> <ng-content select="[slot=environment-selector]"></ng-content> </ng-container> - <ng-container *ngIf="showYearAndVersion"> + <ng-container *ngIf="!hideYearAndVersion"> <div>&copy; {{ year }} Bitwarden Inc.</div> <div>{{ version }}</div> </ng-container> diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.ts b/libs/auth/src/angular/anon-layout/anon-layout.component.ts index 3bd6b2653d1..966cbd3c0e1 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Component, Input } from "@angular/core"; +import { Component, Input, OnChanges, OnInit, SimpleChanges } from "@angular/core"; import { firstValueFrom } from "rxjs"; import { ClientType } from "@bitwarden/common/enums"; @@ -10,7 +10,8 @@ import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-stat import { IconModule, Icon } from "../../../../components/src/icon"; import { SharedModule } from "../../../../components/src/shared"; import { TypographyModule } from "../../../../components/src/typography"; -import { BitwardenLogoPrimary, BitwardenLogoWhite } from "../icons/bitwarden-logo.icon"; +import { BitwardenLogoPrimary, BitwardenLogoWhite } from "../icons"; +import { BitwardenShieldPrimary, BitwardenShieldWhite } from "../icons/bitwarden-shield.icon"; @Component({ standalone: true, @@ -18,11 +19,13 @@ import { BitwardenLogoPrimary, BitwardenLogoWhite } from "../icons/bitwarden-log templateUrl: "./anon-layout.component.html", imports: [IconModule, CommonModule, TypographyModule, SharedModule], }) -export class AnonLayoutComponent { +export class AnonLayoutComponent implements OnInit, OnChanges { @Input() title: string; @Input() subtitle: string; @Input() icon: Icon; @Input() showReadonlyHostname: boolean; + @Input() hideLogo: boolean = false; + @Input() hideFooter: boolean = false; /** * Max width of the layout content * @@ -38,7 +41,7 @@ export class AnonLayoutComponent { protected version: string; protected theme: string; - protected showYearAndVersion = true; + protected hideYearAndVersion = false; constructor( private environmentService: EnvironmentService, @@ -47,13 +50,12 @@ export class AnonLayoutComponent { ) { this.year = new Date().getFullYear().toString(); this.clientType = this.platformUtilsService.getClientType(); - this.showYearAndVersion = this.clientType === ClientType.Web; + this.hideYearAndVersion = this.clientType !== ClientType.Web; } async ngOnInit() { this.maxWidth = this.maxWidth ?? "md"; - this.hostname = (await firstValueFrom(this.environmentService.environment$)).getHostname(); - this.version = await this.platformUtilsService.getApplicationVersion(); + this.theme = await firstValueFrom(this.themeStateService.selectedTheme$); if (this.theme === "dark") { @@ -61,5 +63,29 @@ export class AnonLayoutComponent { } else { this.logo = BitwardenLogoPrimary; } + + await this.updateIcon(this.theme); + + this.hostname = (await firstValueFrom(this.environmentService.environment$)).getHostname(); + this.version = await this.platformUtilsService.getApplicationVersion(); + } + + async ngOnChanges(changes: SimpleChanges) { + if (changes.icon) { + const theme = await firstValueFrom(this.themeStateService.selectedTheme$); + await this.updateIcon(theme); + } + } + + private async updateIcon(theme: string) { + if (this.icon == null) { + if (theme === "dark") { + this.icon = BitwardenShieldWhite; + } + + if (theme !== "dark") { + this.icon = BitwardenShieldPrimary; + } + } } } diff --git a/libs/auth/src/angular/anon-layout/anon-layout.stories.ts b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts index afed1d10470..edf6c8d70a1 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.stories.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts @@ -61,6 +61,7 @@ export default { subtitle: "The subtitle (optional)", showReadonlyHostname: true, icon: LockIcon, + hideLogo: false, }, } as Meta; @@ -144,7 +145,7 @@ export const WithThinPrimaryContent: Story = { }), }; -export const WithIcon: Story = { +export const WithCustomIcon: Story = { render: (args) => ({ props: args, template: @@ -159,3 +160,35 @@ export const WithIcon: Story = { `, }), }; + +export const HideLogo: Story = { + render: (args) => ({ + props: args, + template: + // Projected content (the <div>) and styling is just a sample and can be replaced with any content/styling. + ` + <auth-anon-layout [title]="title" [subtitle]="subtitle" [showReadonlyHostname]="showReadonlyHostname" [hideLogo]="true"> + <div> + <div class="tw-font-bold">Primary Projected Content Area (customizable)</div> + <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus illum vero, placeat recusandae esse ratione eius minima veniam nemo, quas beatae! Impedit molestiae alias sapiente explicabo. Sapiente corporis ipsa numquam?</div> + </div> + </auth-anon-layout> + `, + }), +}; + +export const HideFooter: Story = { + render: (args) => ({ + props: args, + template: + // Projected content (the <div>) and styling is just a sample and can be replaced with any content/styling. + ` + <auth-anon-layout [title]="title" [subtitle]="subtitle" [showReadonlyHostname]="showReadonlyHostname" [hideFooter]="true"> + <div> + <div class="tw-font-bold">Primary Projected Content Area (customizable)</div> + <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus illum vero, placeat recusandae esse ratione eius minima veniam nemo, quas beatae! Impedit molestiae alias sapiente explicabo. Sapiente corporis ipsa numquam?</div> + </div> + </auth-anon-layout> + `, + }), +}; diff --git a/libs/auth/src/angular/icons/bitwarden-shield.icon.ts b/libs/auth/src/angular/icons/bitwarden-shield.icon.ts new file mode 100644 index 00000000000..a81a9906a6b --- /dev/null +++ b/libs/auth/src/angular/icons/bitwarden-shield.icon.ts @@ -0,0 +1,13 @@ +import { svgIcon } from "@bitwarden/components"; + +export const BitwardenShieldPrimary = svgIcon` + <svg viewBox="0 0 120 132" fill="#175DDC" xmlns="http://www.w3.org/2000/svg"> + <path d="M82.2944 69.1899V37.2898H60V93.9624C63.948 91.869 67.4812 89.5927 70.5998 87.1338C78.3962 81.0196 82.2944 75.0383 82.2944 69.1899ZM91.8491 30.9097V69.1899C91.8491 72.0477 91.2934 74.8805 90.182 77.6883C89.0706 80.4962 87.6938 82.9884 86.0516 85.1649C84.4094 87.3415 82.452 89.4598 80.1794 91.5201C77.9068 93.5803 75.8084 95.2916 73.8842 96.654C71.96 98.0164 69.9528 99.304 67.8627 100.517C65.7726 101.73 64.288 102.552 63.4088 102.984C62.5297 103.416 61.8247 103.748 61.2939 103.981C60.8958 104.18 60.4645 104.28 60 104.28C59.5355 104.28 59.1042 104.18 58.7061 103.981C58.1753 103.748 57.4703 103.416 56.5911 102.984C55.712 102.552 54.2273 101.73 52.1372 100.517C50.0471 99.304 48.04 98.0164 46.1158 96.654C44.1916 95.2916 42.0932 93.5803 39.8206 91.5201C37.548 89.4598 35.5906 87.3415 33.9484 85.1649C32.3062 82.9884 30.9294 80.4962 29.818 77.6883C28.7066 74.8805 28.1509 72.0477 28.1509 69.1899V30.9097C28.1509 30.0458 28.4661 29.2981 29.0964 28.6668C29.7267 28.0354 30.4732 27.7197 31.3358 27.7197H88.6642C89.5268 27.7197 90.2732 28.0354 90.9036 28.6668C91.5339 29.2981 91.8491 30.0458 91.8491 30.9097Z" fill="#175DDC"/> + </svg> +`; + +export const BitwardenShieldWhite = svgIcon` + <svg viewBox="0 0 120 132" fill="#FFF" xmlns="http://www.w3.org/2000/svg"> + <path d="M82.2944 69.1899V37.2898H60V93.9624C63.948 91.869 67.4812 89.5927 70.5998 87.1338C78.3962 81.0196 82.2944 75.0383 82.2944 69.1899ZM91.8491 30.9097V69.1899C91.8491 72.0477 91.2934 74.8805 90.182 77.6883C89.0706 80.4962 87.6938 82.9884 86.0516 85.1649C84.4094 87.3415 82.452 89.4598 80.1794 91.5201C77.9068 93.5803 75.8084 95.2916 73.8842 96.654C71.96 98.0164 69.9528 99.304 67.8627 100.517C65.7726 101.73 64.288 102.552 63.4088 102.984C62.5297 103.416 61.8247 103.748 61.2939 103.981C60.8958 104.18 60.4645 104.28 60 104.28C59.5355 104.28 59.1042 104.18 58.7061 103.981C58.1753 103.748 57.4703 103.416 56.5911 102.984C55.712 102.552 54.2273 101.73 52.1372 100.517C50.0471 99.304 48.04 98.0164 46.1158 96.654C44.1916 95.2916 42.0932 93.5803 39.8206 91.5201C37.548 89.4598 35.5906 87.3415 33.9484 85.1649C32.3062 82.9884 30.9294 80.4962 29.818 77.6883C28.7066 74.8805 28.1509 72.0477 28.1509 69.1899V30.9097C28.1509 30.0458 28.4661 29.2981 29.0964 28.6668C29.7267 28.0354 30.4732 27.7197 31.3358 27.7197H88.6642C89.5268 27.7197 90.2732 28.0354 90.9036 28.6668C91.5339 29.2981 91.8491 30.0458 91.8491 30.9097Z" fill="#175DDC"/> + </svg> +`; diff --git a/libs/auth/src/angular/icons/index.ts b/libs/auth/src/angular/icons/index.ts index d71e2e6efde..f502fbe5f3d 100644 --- a/libs/auth/src/angular/icons/index.ts +++ b/libs/auth/src/angular/icons/index.ts @@ -1,3 +1,4 @@ export * from "./bitwarden-logo.icon"; +export * from "./bitwarden-shield.icon"; export * from "./lock.icon"; export * from "./user-verification-biometrics-fingerprint.icon"; diff --git a/libs/auth/src/angular/icons/lock.icon.ts b/libs/auth/src/angular/icons/lock.icon.ts index b567c213f70..981b520010a 100644 --- a/libs/auth/src/angular/icons/lock.icon.ts +++ b/libs/auth/src/angular/icons/lock.icon.ts @@ -1,7 +1,17 @@ import { svgIcon } from "@bitwarden/components"; export const LockIcon = svgIcon` - <svg width="65" height="80" fill="none" xmlns="http://www.w3.org/2000/svg"> - <path class="tw-fill-primary-600" d="M36.554 52.684a4.133 4.133 0 0 0-.545-2.085 4.088 4.088 0 0 0-1.514-1.518 4.022 4.022 0 0 0-4.114.072 4.094 4.094 0 0 0-1.461 1.57 4.153 4.153 0 0 0 .175 4.16c.393.616.94 1.113 1.588 1.44v6.736a1.864 1.864 0 0 0 .498 1.365c.17.18.376.328.603.425a1.781 1.781 0 0 0 1.437 0c.227-.097.432-.242.603-.425a1.864 1.864 0 0 0 .499-1.365v-6.745a4.05 4.05 0 0 0 1.62-1.498c.392-.64.604-1.377.611-2.132ZM57.86 25.527h-2.242c-.175 0-.35-.037-.514-.105a1.3 1.3 0 0 1-.434-.297 1.379 1.379 0 0 1-.39-.963v-1a23 23 0 0 0-5.455-15.32A22.46 22.46 0 0 0 34.673.101a21.633 21.633 0 0 0-8.998 1.032 21.777 21.777 0 0 0-7.813 4.637 22.118 22.118 0 0 0-5.286 7.446 22.376 22.376 0 0 0-1.855 8.975v1.62c0 .03-.118 1.705-1.555 1.73h-2.02A6.723 6.723 0 0 0 2.37 27.56 6.887 6.887 0 0 0 .4 32.403V73.12a6.905 6.905 0 0 0 1.97 4.847A6.76 6.76 0 0 0 7.146 80h50.713a6.746 6.746 0 0 0 4.77-2.03 6.925 6.925 0 0 0 1.971-4.845V32.403a6.91 6.91 0 0 0-1.965-4.85 6.793 6.793 0 0 0-2.19-1.493 6.676 6.676 0 0 0-2.588-.53l.002-.003Zm-42.2-3.335c-.007-2.55.549-5.07 1.625-7.373a17.085 17.085 0 0 1 4.606-5.945 16.8 16.8 0 0 1 6.684-3.358 16.71 16.71 0 0 1 7.462-.115c3.835.91 7.245 3.12 9.665 6.266a17.61 17.61 0 0 1 3.64 11.02v1.475c0 .18-.035.358-.102.523a1.349 1.349 0 0 1-1.244.842H17.722a1.876 1.876 0 0 1-.744-.085 1.894 1.894 0 0 1-1.119-.957 1.98 1.98 0 0 1-.204-.728v-1.565h.005ZM59.663 73.12c0 .487-.19.952-.529 1.3a1.796 1.796 0 0 1-1.279.545H7.146a1.826 1.826 0 0 1-1.807-1.845V32.403a1.85 1.85 0 0 1 .523-1.3c.168-.17.365-.308.585-.4.22-.093.454-.14.691-.143h50.719c.479.005.938.2 1.276.545.339.345.526.81.526 1.295v40.717l.003.003Z" /> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 100" fill="none"> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M27.5 48.218a9 9 0 0 1 9-9h47a9 9 0 0 1 9 9v7.5h-2v-7.5a7 7 0 0 0-7-7h-47a7 7 0 0 0-7 7v7.5h-2v-7.5Zm2 30.75v3.75a7 7 0 0 0 7 7h47a7 7 0 0 0 7-7v-3.75h2v3.75a9 9 0 0 1-9 9h-47a9 9 0 0 1-9-9v-3.75h2Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M60 10.718c-11.144 0-20 7.942-20 17.414v11.586h-2V28.132C38 17.317 48.007 8.718 60 8.718c11.991 0 22 8.552 22 19.414v11.586h-2V28.132c0-9.516-8.855-17.414-20-17.414ZM32.028 61.28a1 1 0 0 1 1 1v5.678a1 1 0 1 1-2 0v-5.679a1 1 0 0 1 1-1Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M38.452 65.897a1 1 0 0 1-.647 1.258l-5.472 1.755a1 1 0 1 1-.61-1.904l5.471-1.755a1 1 0 0 1 1.258.646Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M31.442 67.147a1 1 0 0 1 1.396.225l3.356 4.646a1 1 0 0 1-1.622 1.171l-3.355-4.646a1 1 0 0 1 .225-1.396Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M32.607 67.143a1 1 0 0 1 .236 1.394l-3.304 4.646a1 1 0 0 1-1.63-1.159l3.304-4.646a1 1 0 0 1 1.394-.235Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M25.656 65.895a1 1 0 0 1 1.26-.644l5.42 1.755a1 1 0 1 1-.616 1.903l-5.42-1.755a1 1 0 0 1-.644-1.26ZM50.508 61.28a1 1 0 0 1 1 1v5.678a1 1 0 1 1-2 0v-5.679a1 1 0 0 1 1-1Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M56.88 65.895a1 1 0 0 1-.644 1.26l-5.42 1.754a1 1 0 1 1-.616-1.903l5.42-1.755a1 1 0 0 1 1.26.644Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M49.922 67.147a1 1 0 0 1 1.397.225l3.355 4.646a1 1 0 1 1-1.621 1.171l-3.356-4.646a1 1 0 0 1 .225-1.396Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M51.093 67.147a1 1 0 0 1 .226 1.396l-3.356 4.646a1 1 0 0 1-1.621-1.17l3.355-4.647a1 1 0 0 1 1.396-.225Z" clip-rule="evenodd"/> + <path class="tw-fill-text-headers" fill-rule="evenodd" d="M44.136 65.895a1 1 0 0 1 1.26-.644l5.42 1.755a1 1 0 1 1-.616 1.903l-5.42-1.755a1 1 0 0 1-.644-1.26ZM62.568 72.603a1 1 0 0 1 1-1h10.84a1 1 0 1 1 0 2h-10.84a1 1 0 0 1-1-1ZM81.049 72.603a1 1 0 0 1 1-1h10.84a1 1 0 1 1 0 2H82.05a1 1 0 0 1-1-1Z" clip-rule="evenodd"/> + <path class="tw-fill-info-600" fill-rule="evenodd" d="M17.5 67.468c0-7.042 5.708-12.75 12.75-12.75h59.5c7.041 0 12.75 5.708 12.75 12.75s-5.709 12.75-12.75 12.75h-59.5c-7.042 0-12.75-5.708-12.75-12.75Zm12.75-10.75c-5.937 0-10.75 4.813-10.75 10.75s4.813 10.75 10.75 10.75h59.5c5.937 0 10.75-4.813 10.75-10.75s-4.813-10.75-10.75-10.75h-59.5Z" clip-rule="evenodd"/> </svg> `; From cbac5fde11d6677648ca28b46bb75d6d7a871077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= <ajensen@bitwarden.com> Date: Tue, 30 Jul 2024 15:39:49 -0400 Subject: [PATCH 41/46] [PM-10259] improve forwarder rpc error handling (#10330) * only accept `application/json` responses --- libs/common/src/tools/integration/rpc/rest-client.ts | 3 ++- .../core/src/engine/rpc/create-forwarding-address.spec.ts | 2 +- .../core/src/engine/rpc/create-forwarding-address.ts | 4 +--- .../generator/core/src/engine/rpc/get-account-id.spec.ts | 1 + libs/tools/generator/core/src/engine/rpc/get-account-id.ts | 1 + 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libs/common/src/tools/integration/rpc/rest-client.ts b/libs/common/src/tools/integration/rpc/rest-client.ts index 05abb047d38..c9096d0ce1d 100644 --- a/libs/common/src/tools/integration/rpc/rest-client.ts +++ b/libs/common/src/tools/integration/rpc/rest-client.ts @@ -48,7 +48,7 @@ export class RestClient { const message = await this.tryGetErrorMessage(response); const key = message ? "forwaderInvalidTokenWithMessage" : "forwaderInvalidToken"; return [key, message]; - } else if (response.status === 429 || response.status >= 500) { + } else if (response.status >= 400) { const message = await this.tryGetErrorMessage(response); const key = message ? "forwarderError" : "forwarderUnknownError"; return [key, message]; @@ -59,6 +59,7 @@ export class RestClient { const body = (await response.text()) ?? ""; // nullish continues processing; false returns undefined + // FIXME: inspect content-type header to determine extraction process const error = this.tryFindErrorAsJson(body) ?? this.tryFindErrorAsText(body) ?? response.statusText; diff --git a/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts index d522b5f38ed..b0459e16a79 100644 --- a/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts +++ b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.spec.ts @@ -37,7 +37,7 @@ describe("CreateForwardingAddressRpc", () => { expect(result.cache).toEqual("no-store"); expect(result.method).toEqual("POST"); expect(result.headers.get("Content-Type")).toEqual("application/json"); - expect(result.headers.get("X-Requested-With")).toEqual("XMLHttpRequest"); + expect(result.headers.get("Accept")).toEqual("application/json"); }); it("provides the request and context to the rpc definition functions", () => { diff --git a/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts index 210a7a1b21c..4d4a5ba2ded 100644 --- a/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts +++ b/libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts @@ -29,10 +29,8 @@ export class CreateForwardingAddressRpc< method: "POST", headers: new Headers({ ...token, - // X-Requested-With header required by some endpoints for - // detailed error descriptions (see #5565) - "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/json", + Accept: "application/json", }), body, }); diff --git a/libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts b/libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts index 1772bf9901c..6bbfb691d8d 100644 --- a/libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts +++ b/libs/tools/generator/core/src/engine/rpc/get-account-id.spec.ts @@ -32,6 +32,7 @@ describe("GetAccountIdRpc", () => { expect(result.cache).toEqual("no-store"); expect(result.method).toEqual("GET"); expect(result.headers.get("Content-Type")).toEqual("application/json"); + expect(result.headers.get("Accept")).toEqual("application/json"); }); it("provides the request and context to the rpc definition functions", () => { diff --git a/libs/tools/generator/core/src/engine/rpc/get-account-id.ts b/libs/tools/generator/core/src/engine/rpc/get-account-id.ts index 4e90df77ff0..17bb24e4781 100644 --- a/libs/tools/generator/core/src/engine/rpc/get-account-id.ts +++ b/libs/tools/generator/core/src/engine/rpc/get-account-id.ts @@ -33,6 +33,7 @@ export class GetAccountIdRpc< headers: new Headers({ ...token, "Content-Type": "application/json", + Accept: "application/json", }), }); From 80af356fd1817c55faba866364e5ef18d5b29997 Mon Sep 17 00:00:00 2001 From: Jason Ng <jng@bitwarden.com> Date: Tue, 30 Jul 2024 15:54:45 -0400 Subject: [PATCH 42/46] [PM-7901] added new card view (#10321) * added new card view --- .../additional-options.component.html | 4 +- .../card-details-view.component.html | 83 ++++++++++++++ .../card-details-view.component.ts | 45 ++++++++ .../cipher-view/cipher-view.component.html | 5 + .../src/cipher-view/cipher-view.component.ts | 7 ++ .../custom-fields-v2.component.html | 104 ++++++++---------- 6 files changed, 186 insertions(+), 62 deletions(-) create mode 100644 libs/vault/src/cipher-view/card-details/card-details-view.component.html create mode 100644 libs/vault/src/cipher-view/card-details/card-details-view.component.ts diff --git a/libs/vault/src/cipher-view/additional-options/additional-options.component.html b/libs/vault/src/cipher-view/additional-options/additional-options.component.html index 1650ba2d128..1f33bb78825 100644 --- a/libs/vault/src/cipher-view/additional-options/additional-options.component.html +++ b/libs/vault/src/cipher-view/additional-options/additional-options.component.html @@ -3,10 +3,8 @@ <h2 bitTypography="h6">{{ "additionalOptions" | i18n }}</h2> </bit-section-header> <bit-card> - <label class="tw-text-xs tw-text-muted tw-select-none"> - {{ "note" | i18n }} - </label> <bit-form-field> + <bit-label>{{ "note" | i18n }}</bit-label> <textarea readonly bitInput aria-readonly="true">{{ notes }}</textarea> <button bitSuffix diff --git a/libs/vault/src/cipher-view/card-details/card-details-view.component.html b/libs/vault/src/cipher-view/card-details/card-details-view.component.html new file mode 100644 index 00000000000..c831ae1d944 --- /dev/null +++ b/libs/vault/src/cipher-view/card-details/card-details-view.component.html @@ -0,0 +1,83 @@ +<bit-section> + <bit-section-header> + <h2 bitTypography="h6">{{ setSectionTitle }}</h2> + </bit-section-header> + <bit-card> + <bit-form-field> + <bit-label>{{ "cardholderName" | i18n }}</bit-label> + <input + readonly + bitInput + type="text" + [value]="card.cardholderName" + aria-readonly="true" + data-testid="cardholder-name" + /> + </bit-form-field> + <bit-form-field *ngIf="card.number" [disableMargin]="!card.expiration && !card.code"> + <bit-label>{{ "number" | i18n }}</bit-label> + <input + readonly + bitInput + type="password" + [value]="card.number" + aria-readonly="true" + data-testid="cardholder-number" + /> + <button + bitSuffix + type="button" + bitIconButton + bitPasswordInputToggle + data-testid="toggle-number" + ></button> + <button + bitIconButton="bwi-clone" + bitSuffix + type="button" + [appCopyClick]="card.number" + showToast + [appA11yTitle]="'copyValue' | i18n" + data-testid="copy-number" + ></button> + </bit-form-field> + <bit-form-field *ngIf="card.expiration" [disableMargin]="!card.code"> + <bit-label>{{ "expiration" | i18n }}</bit-label> + <input + readonly + bitInput + type="text" + [value]="card.expiration" + aria-readonly="true" + data-testid="cardholder-expiration" + /> + </bit-form-field> + <bit-form-field *ngIf="card.code" disableMargin> + <bit-label>{{ "securityCode" | i18n }}</bit-label> + <input + readonly + bitInput + type="password" + [value]="card.code" + aria-readonly="true" + data-testid="cardholder-code" + /> + <button + bitSuffix + type="button" + bitIconButton + bitPasswordInputToggle + data-testid="toggle-code" + ></button> + <button + bitIconButton="bwi-clone" + bitSuffix + type="button" + [appCopyClick]="card.code" + showToast + [appA11yTitle]="'copyValue' | i18n" + data-testid="copy-code" + ></button> + </bit-form-field> + </bit-card> +</bit-section> diff --git a/libs/vault/src/cipher-view/card-details/card-details-view.component.ts b/libs/vault/src/cipher-view/card-details/card-details-view.component.ts new file mode 100644 index 00000000000..a3c55977a28 --- /dev/null +++ b/libs/vault/src/cipher-view/card-details/card-details-view.component.ts @@ -0,0 +1,45 @@ +import { CommonModule } from "@angular/common"; +import { Component, Input } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { CardView } from "@bitwarden/common/vault/models/view/card.view"; +import { + CardComponent, + SectionComponent, + SectionHeaderComponent, + TypographyModule, + FormFieldModule, + IconButtonModule, +} from "@bitwarden/components"; + +import { OrgIconDirective } from "../../components/org-icon.directive"; + +@Component({ + selector: "app-card-details-view", + templateUrl: "card-details-view.component.html", + standalone: true, + imports: [ + CommonModule, + JslibModule, + CardComponent, + SectionComponent, + SectionHeaderComponent, + TypographyModule, + OrgIconDirective, + FormFieldModule, + IconButtonModule, + ], +}) +export class CardDetailsComponent { + @Input() card: CardView; + + constructor(private i18nService: I18nService) {} + + get setSectionTitle() { + if (this.card.brand && this.card.brand !== "Other") { + return this.i18nService.t("cardBrandDetails", this.card.brand); + } + return this.i18nService.t("cardDetails"); + } +} diff --git a/libs/vault/src/cipher-view/cipher-view.component.html b/libs/vault/src/cipher-view/cipher-view.component.html index 1463cbd7315..6046bb48fd6 100644 --- a/libs/vault/src/cipher-view/cipher-view.component.html +++ b/libs/vault/src/cipher-view/cipher-view.component.html @@ -8,6 +8,11 @@ > </app-item-details-v2> + <!-- CARD DETAILS --> + <ng-container *ngIf="hasCard"> + <app-card-details-view [card]="cipher.card"></app-card-details-view> + </ng-container> + <!-- IDENTITY SECTIONS --> <app-view-identity-sections *ngIf="cipher.identity" [cipher]="cipher"> </app-view-identity-sections> diff --git a/libs/vault/src/cipher-view/cipher-view.component.ts b/libs/vault/src/cipher-view/cipher-view.component.ts index 7e72424e1f0..094a3e72c75 100644 --- a/libs/vault/src/cipher-view/cipher-view.component.ts +++ b/libs/vault/src/cipher-view/cipher-view.component.ts @@ -19,6 +19,7 @@ import { PopupPageComponent } from "../../../../apps/browser/src/platform/popup/ import { AdditionalOptionsComponent } from "./additional-options/additional-options.component"; import { AttachmentsV2ViewComponent } from "./attachments/attachments-v2-view.component"; +import { CardDetailsComponent } from "./card-details/card-details-view.component"; import { CustomFieldV2Component } from "./custom-fields/custom-fields-v2.component"; import { ItemDetailsV2Component } from "./item-details/item-details-v2.component"; import { ItemHistoryV2Component } from "./item-history/item-history-v2.component"; @@ -40,6 +41,7 @@ import { ViewIdentitySectionsComponent } from "./view-identity-sections/view-ide AttachmentsV2ViewComponent, ItemHistoryV2Component, CustomFieldV2Component, + CardDetailsComponent, ViewIdentitySectionsComponent, ], }) @@ -64,6 +66,11 @@ export class CipherViewComponent implements OnInit { this.destroyed$.complete(); } + get hasCard() { + const { cardholderName, code, expMonth, expYear, brand, number } = this.cipher.card; + return cardholderName || code || expMonth || expYear || brand || number; + } + async loadCipherData() { if (this.cipher.collectionIds.length > 0) { this.collections$ = this.collectionService diff --git a/libs/vault/src/cipher-view/custom-fields/custom-fields-v2.component.html b/libs/vault/src/cipher-view/custom-fields/custom-fields-v2.component.html index 0adb8535fa3..39d261d1bc7 100644 --- a/libs/vault/src/cipher-view/custom-fields/custom-fields-v2.component.html +++ b/libs/vault/src/cipher-view/custom-fields/custom-fields-v2.component.html @@ -8,65 +8,51 @@ *ngFor="let field of fields; let last = last" [ngClass]="{ 'tw-mb-4': !last }" > - <ng-container *ngIf="field.type === fieldType.Text"> - <label class="tw-text-xs tw-text-muted tw-select-none"> - {{ field.name }} - </label> - <bit-form-field> - <input readonly bitInput type="text" [value]="field.value" aria-readonly="true" /> - <button - bitIconButton="bwi-clone" - bitSuffix - type="button" - [appCopyClick]="field.value" - showToast - [appA11yTitle]="'copyValue' | i18n" - ></button> - </bit-form-field> - </ng-container> - <ng-container *ngIf="field.type === fieldType.Hidden"> - <label class="tw-text-xs tw-text-muted tw-select-none"> - {{ field.name }} - </label> - <bit-form-field> - <input readonly bitInput type="password" [value]="field.value" aria-readonly="true" /> - <button bitSuffix type="button" bitIconButton bitPasswordInputToggle></button> - <button - bitIconButton="bwi-clone" - bitSuffix - type="button" - [appCopyClick]="field.value" - showToast - [appA11yTitle]="'copyValue' | i18n" - ></button> - </bit-form-field> - </ng-container> - <ng-container *ngIf="field.type === fieldType.Boolean"> - <bit-form-control> - <input - bitCheckbox - type="checkbox" - [checked]="field.value === 'true'" - aria-readonly="true" - disabled - /> - <bit-label> {{ field.name }} </bit-label> - </bit-form-control> - </ng-container> - <ng-container *ngIf="field.type === fieldType.Linked"> - <label class="tw-text-xs tw-text-muted tw-select-none"> - {{ "linked" | i18n }}: {{ field.name }} - </label> - <bit-form-field> - <input - readonly - bitInput - type="text" - [value]="getLinkedType(field.linkedId)" - aria-readonly="true" - /> - </bit-form-field> - </ng-container> + <bit-form-field *ngIf="field.type === fieldType.Text"> + <bit-label>{{ field.name }}</bit-label> + <input readonly bitInput type="text" [value]="field.value" aria-readonly="true" /> + <button + bitIconButton="bwi-clone" + bitSuffix + type="button" + [appCopyClick]="field.value" + showToast + [appA11yTitle]="'copyValue' | i18n" + ></button> + </bit-form-field> + <bit-form-field *ngIf="field.type === fieldType.Hidden"> + <bit-label>{{ field.name }}</bit-label> + <input readonly bitInput type="password" [value]="field.value" aria-readonly="true" /> + <button bitSuffix type="button" bitIconButton bitPasswordInputToggle></button> + <button + bitIconButton="bwi-clone" + bitSuffix + type="button" + [appCopyClick]="field.value" + showToast + [appA11yTitle]="'copyValue' | i18n" + ></button> + </bit-form-field> + <bit-form-control *ngIf="field.type === fieldType.Boolean"> + <input + bitCheckbox + type="checkbox" + [checked]="field.value === 'true'" + aria-readonly="true" + disabled + /> + <bit-label> {{ field.name }} </bit-label> + </bit-form-control> + <bit-form-field *ngIf="field.type === fieldType.Linked"> + <bit-label> {{ "linked" | i18n }}: {{ field.name }} </bit-label> + <input + readonly + bitInput + type="text" + [value]="getLinkedType(field.linkedId)" + aria-readonly="true" + /> + </bit-form-field> </div> </bit-card> </bit-section> From 22d3a3e280a1b9c4534cfba018528f50173b8a9b Mon Sep 17 00:00:00 2001 From: Jason Ng <jng@bitwarden.com> Date: Tue, 30 Jul 2024 16:28:48 -0400 Subject: [PATCH 43/46] PM-7901 Add disableMargin to name field in card details (#10334) --- .../cipher-view/card-details/card-details-view.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/vault/src/cipher-view/card-details/card-details-view.component.html b/libs/vault/src/cipher-view/card-details/card-details-view.component.html index c831ae1d944..108b148016b 100644 --- a/libs/vault/src/cipher-view/card-details/card-details-view.component.html +++ b/libs/vault/src/cipher-view/card-details/card-details-view.component.html @@ -3,7 +3,7 @@ <h2 bitTypography="h6">{{ setSectionTitle }}</h2> </bit-section-header> <bit-card> - <bit-form-field> + <bit-form-field [disableMargin]="!card.number && !card.expiration && !card.code"> <bit-label>{{ "cardholderName" | i18n }}</bit-label> <input readonly From 17e0dff3423392f56ee84b4ec5bae07f3a8c0db5 Mon Sep 17 00:00:00 2001 From: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Date: Tue, 30 Jul 2024 14:40:34 -0700 Subject: [PATCH 44/46] Bumped client version(s) (#10335) --- apps/cli/package.json | 2 +- package-lock.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/cli/package.json b/apps/cli/package.json index 7a43ee759fa..8b541551eed 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/cli", "description": "A secure and free password manager for all of your devices.", - "version": "2024.7.1", + "version": "2024.7.2", "keywords": [ "bitwarden", "password", diff --git a/package-lock.json b/package-lock.json index ea39aef5043..3e50bb0e131 100644 --- a/package-lock.json +++ b/package-lock.json @@ -199,7 +199,7 @@ }, "apps/cli": { "name": "@bitwarden/cli", - "version": "2024.7.1", + "version": "2024.7.2", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@koa/multer": "3.0.2", From 27fa7625cf749c4993f687f75fe5bc0aed22d9bd Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Tue, 30 Jul 2024 21:27:00 -0500 Subject: [PATCH 45/46] add option to make button block/inline (#10197) --- .../angular/input-password/input-password.component.html | 2 +- .../angular/input-password/input-password.component.ts | 1 + .../src/angular/input-password/input-password.stories.ts | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/auth/src/angular/input-password/input-password.component.html b/libs/auth/src/angular/input-password/input-password.component.html index 54c832fbd64..114d9b8fb8d 100644 --- a/libs/auth/src/angular/input-password/input-password.component.html +++ b/libs/auth/src/angular/input-password/input-password.component.html @@ -70,7 +70,7 @@ bitButton bitFormButton buttonType="primary" - [block]="true" + [block]="btnBlock" [loading]="loading" > {{ buttonText || ("setMasterPassword" | i18n) }} diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index 23282bd2894..0aecb6e3783 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -56,6 +56,7 @@ export class InputPasswordComponent { @Input() buttonText: string; @Input() masterPasswordPolicyOptions: MasterPasswordPolicyOptions | null = null; @Input() loading: boolean = false; + @Input() btnBlock: boolean = true; private minHintLength = 0; protected maxHintLength = 50; diff --git a/libs/auth/src/angular/input-password/input-password.stories.ts b/libs/auth/src/angular/input-password/input-password.stories.ts index feccd8ccba5..1d7459cd009 100644 --- a/libs/auth/src/angular/input-password/input-password.stories.ts +++ b/libs/auth/src/angular/input-password/input-password.stories.ts @@ -113,3 +113,12 @@ export const WithPolicy: Story = { `, }), }; + +export const InlineButton: Story = { + render: (args) => ({ + props: args, + template: ` + <auth-input-password [btnBlock]="false" [masterPasswordPolicyOptions]="masterPasswordPolicyOptions"></auth-input-password> + `, + }), +}; From 4a0b6fc191d742760688ebfd0e707985667a628d Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 31 Jul 2024 09:27:16 -0400 Subject: [PATCH 46/46] Update client side error handling and remove add account credit from sub (#10214) --- .../services/web-provider.service.ts | 2 +- .../provider-billing-history.component.ts | 36 +++---- .../manage-client-name-dialog.component.ts | 2 +- ...ge-client-subscription-dialog.component.ts | 2 +- .../clients/manage-clients.component.ts | 17 ++-- .../provider-subscription.component.html | 3 - .../provider-subscription.component.ts | 15 +-- .../src/services/jslib-services.module.ts | 2 +- .../billilng-api.service.abstraction.ts | 25 +++-- .../billing/services/billing-api.service.ts | 99 ++++++++++++------- .../payment-method-warnings.service.spec.ts | 14 +-- .../payment-method-warnings.service.ts | 2 +- 12 files changed, 114 insertions(+), 105 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts index 4195ffcb057..16b2d51de47 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts @@ -71,7 +71,7 @@ export class WebProviderService { request.keyPair = new OrganizationKeysRequest(publicKey, encryptedPrivateKey.encryptedString); request.collectionName = encryptedCollectionName.encryptedString; - await this.billingApiService.createClientOrganization(providerId, request); + await this.billingApiService.createProviderClientOrganization(providerId, request); await this.apiService.refreshIdentityToken(); diff --git a/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts index d8385e87b39..70dd9d676b3 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts @@ -1,7 +1,8 @@ import { DatePipe } from "@angular/common"; -import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Component } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute } from "@angular/router"; -import { map, Subject, takeUntil } from "rxjs"; +import { map } from "rxjs"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions"; import { InvoiceResponse } from "@bitwarden/common/billing/models/response/invoices.response"; @@ -9,16 +10,23 @@ import { InvoiceResponse } from "@bitwarden/common/billing/models/response/invoi @Component({ templateUrl: "./provider-billing-history.component.html", }) -export class ProviderBillingHistoryComponent implements OnInit, OnDestroy { +export class ProviderBillingHistoryComponent { private providerId: string; - private destroy$ = new Subject<void>(); - constructor( private activatedRoute: ActivatedRoute, private billingApiService: BillingApiServiceAbstraction, private datePipe: DatePipe, - ) {} + ) { + this.activatedRoute.params + .pipe( + map(({ providerId }) => { + this.providerId = providerId; + }), + takeUntilDestroyed(), + ) + .subscribe(); + } getClientInvoiceReport = (invoiceId: string) => this.billingApiService.getProviderClientInvoiceReport(this.providerId, invoiceId); @@ -29,20 +37,4 @@ export class ProviderBillingHistoryComponent implements OnInit, OnDestroy { }; getInvoices = async () => await this.billingApiService.getProviderInvoices(this.providerId); - - ngOnInit() { - this.activatedRoute.params - .pipe( - map(({ providerId }) => { - this.providerId = providerId; - }), - takeUntil(this.destroy$), - ) - .subscribe(); - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } } diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts index be46308c1c4..20b7e9aaa7b 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts @@ -59,7 +59,7 @@ export class ManageClientNameDialogComponent { request.assignedSeats = this.dialogParams.organization.seats; request.name = this.formGroup.value.name; - await this.billingApiService.updateClientOrganization( + await this.billingApiService.updateProviderClientOrganization( this.dialogParams.providerId, this.dialogParams.organization.id, request, diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts index f92223d1b54..b87c110ee32 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts @@ -93,7 +93,7 @@ export class ManageClientSubscriptionDialogComponent implements OnInit { request.assignedSeats = this.formGroup.value.assignedSeats; request.name = this.dialogParams.organization.organizationName; - await this.billingApiService.updateClientOrganization( + await this.billingApiService.updateProviderClientOrganization( this.dialogParams.provider.id, this.dialogParams.organization.id, request, diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts index 7d3cd139117..03ef71482fb 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-clients.component.ts @@ -1,9 +1,9 @@ import { Component } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute, Router } from "@angular/router"; import { firstValueFrom, from, lastValueFrom, map } from "rxjs"; -import { switchMap, takeUntil } from "rxjs/operators"; +import { switchMap } from "rxjs/operators"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; import { ProviderUserType } from "@bitwarden/common/admin-console/enums"; @@ -46,7 +46,6 @@ export class ManageClientsComponent extends BaseClientsComponent { protected plans: PlanResponse[]; constructor( - private apiService: ApiService, private billingApiService: BillingApiService, private configService: ConfigService, private providerService: ProviderService, @@ -68,9 +67,7 @@ export class ManageClientsComponent extends BaseClientsComponent { validationService, webProviderService, ); - } - ngOnInit() { this.activatedRoute.parent.params .pipe( switchMap((params) => { @@ -90,15 +87,11 @@ export class ManageClientsComponent extends BaseClientsComponent { }), ); }), - takeUntil(this.destroy$), + takeUntilDestroyed(), ) .subscribe(); } - ngOnDestroy() { - super.ngOnDestroy(); - } - removeMonthly = (plan: string) => plan.replace(" (Monthly)", ""); async load() { @@ -106,7 +99,9 @@ export class ManageClientsComponent extends BaseClientsComponent { this.isProviderAdmin = this.provider.type === ProviderUserType.ProviderAdmin; - this.clients = (await this.apiService.getProviderClients(this.providerId)).data; + this.clients = ( + await this.billingApiService.getProviderClientOrganizations(this.providerId) + ).data; this.dataSource.data = this.clients; diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html index f47df92efaf..55675f2186d 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html @@ -69,9 +69,6 @@ </h2> <p class="tw-text-lg tw-font-bold">{{ subscription.accountCredit | currency: "$" }}</p> <p bitTypography="body1">{{ "creditAppliedDesc" | i18n }}</p> - <button type="button" bitButton buttonType="secondary" [bitAction]="addAccountCredit"> - {{ "addCredit" | i18n }} - </button> </ng-container> <!-- Tax Information --> <ng-container> diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts index d582ad071fc..38f366f6141 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts @@ -2,7 +2,6 @@ import { Component } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { Subject, concatMap, takeUntil } from "rxjs"; -import { openAddAccountCreditDialog } from "@bitwarden/angular/billing/components"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction"; import { TaxInformation } from "@bitwarden/common/billing/models/domain"; import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request"; @@ -11,7 +10,7 @@ import { ProviderSubscriptionResponse, } from "@bitwarden/common/billing/models/response/provider-subscription-response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { DialogService, ToastService } from "@bitwarden/components"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-provider-subscription", @@ -27,9 +26,10 @@ export class ProviderSubscriptionComponent { totalCost: number; currentDate = new Date(); + protected readonly TaxInformation = TaxInformation; + constructor( private billingApiService: BillingApiServiceAbstraction, - private dialogService: DialogService, private i18nService: I18nService, private route: ActivatedRoute, private toastService: ToastService, @@ -63,13 +63,6 @@ export class ProviderSubscriptionComponent { this.loading = false; } - addAccountCredit = () => - openAddAccountCreditDialog(this.dialogService, { - data: { - providerId: this.providerId, - }, - }); - updateTaxInformation = async (taxInformation: TaxInformation) => { const request = ExpandedTaxInfoUpdateRequest.From(taxInformation); await this.billingApiService.updateProviderTaxInformation(this.providerId, request); @@ -108,6 +101,4 @@ export class ProviderSubscriptionComponent { this.destroy$.next(); this.destroy$.complete(); } - - protected readonly TaxInformation = TaxInformation; } diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 5427c586af1..db1eb1a577f 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1196,7 +1196,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: BillingApiServiceAbstraction, useClass: BillingApiService, - deps: [ApiServiceAbstraction], + deps: [ApiServiceAbstraction, LogService, ToastService], }), safeProvider({ provide: PaymentMethodWarningsServiceAbstraction, diff --git a/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts b/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts index de3d6dd1e98..83db2fcd878 100644 --- a/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts +++ b/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts @@ -1,3 +1,4 @@ +import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response"; import { PaymentMethodType } from "@bitwarden/common/billing/enums"; import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request"; import { TokenizedPaymentMethodRequest } from "@bitwarden/common/billing/models/request/tokenized-payment-method.request"; @@ -8,7 +9,6 @@ import { PaymentInformationResponse } from "@bitwarden/common/billing/models/res import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request"; import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response"; import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response"; -import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.response"; import { PlanResponse } from "../../billing/models/response/plan.response"; import { ListResponse } from "../../models/response/list.response"; import { CreateClientOrganizationRequest } from "../models/request/create-client-organization.request"; @@ -23,39 +23,45 @@ export abstract class BillingApiServiceAbstraction { cancelPremiumUserSubscription: (request: SubscriptionCancellationRequest) => Promise<void>; - createClientOrganization: ( + createProviderClientOrganization: ( providerId: string, request: CreateClientOrganizationRequest, ) => Promise<void>; createSetupIntent: (paymentMethodType: PaymentMethodType) => Promise<string>; - getBillingStatus: (id: string) => Promise<OrganizationBillingStatusResponse>; - getOrganizationBillingMetadata: ( organizationId: string, ) => Promise<OrganizationBillingMetadataResponse>; - getOrganizationSubscription: ( - organizationId: string, - ) => Promise<OrganizationSubscriptionResponse>; + getOrganizationBillingStatus: (id: string) => Promise<OrganizationBillingStatusResponse>; getPlans: () => Promise<ListResponse<PlanResponse>>; getProviderClientInvoiceReport: (providerId: string, invoiceId: string) => Promise<string>; + getProviderClientOrganizations: ( + providerId: string, + ) => Promise<ListResponse<ProviderOrganizationOrganizationDetailsResponse>>; + getProviderInvoices: (providerId: string) => Promise<InvoicesResponse>; + /** + * @deprecated This endpoint is currently deactivated. + */ getProviderPaymentInformation: (providerId: string) => Promise<PaymentInformationResponse>; getProviderSubscription: (providerId: string) => Promise<ProviderSubscriptionResponse>; - updateClientOrganization: ( + updateProviderClientOrganization: ( providerId: string, organizationId: string, request: UpdateClientOrganizationRequest, ) => Promise<any>; + /** + * @deprecated This endpoint is currently deactivated. + */ updateProviderPaymentMethod: ( providerId: string, request: TokenizedPaymentMethodRequest, @@ -66,6 +72,9 @@ export abstract class BillingApiServiceAbstraction { request: ExpandedTaxInfoUpdateRequest, ) => Promise<void>; + /** + * @deprecated This endpoint is currently deactivated. + */ verifyProviderBankAccount: ( providerId: string, request: VerifyBankAccountRequest, diff --git a/libs/common/src/billing/services/billing-api.service.ts b/libs/common/src/billing/services/billing-api.service.ts index 333c9ab0119..a5841fc5b55 100644 --- a/libs/common/src/billing/services/billing-api.service.ts +++ b/libs/common/src/billing/services/billing-api.service.ts @@ -1,4 +1,8 @@ +import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response"; import { InvoicesResponse } from "@bitwarden/common/billing/models/response/invoices.response"; +import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { ToastService } from "@bitwarden/components"; import { ApiService } from "../../abstractions/api.service"; import { BillingApiServiceAbstraction } from "../../billing/abstractions"; @@ -9,7 +13,6 @@ import { TokenizedPaymentMethodRequest } from "../../billing/models/request/toke import { VerifyBankAccountRequest } from "../../billing/models/request/verify-bank-account.request"; import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response"; import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response"; -import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.response"; import { PaymentInformationResponse } from "../../billing/models/response/payment-information.response"; import { PlanResponse } from "../../billing/models/response/plan.response"; import { ListResponse } from "../../models/response/list.response"; @@ -18,7 +21,11 @@ import { UpdateClientOrganizationRequest } from "../models/request/update-client import { ProviderSubscriptionResponse } from "../models/response/provider-subscription-response"; export class BillingApiService implements BillingApiServiceAbstraction { - constructor(private apiService: ApiService) {} + constructor( + private apiService: ApiService, + private logService: LogService, + private toastService: ToastService, + ) {} cancelOrganizationSubscription( organizationId: string, @@ -37,7 +44,7 @@ export class BillingApiService implements BillingApiServiceAbstraction { return this.apiService.send("POST", "/accounts/cancel", request, true, false); } - createClientOrganization( + createProviderClientOrganization( providerId: string, request: CreateClientOrganizationRequest, ): Promise<void> { @@ -65,7 +72,7 @@ export class BillingApiService implements BillingApiServiceAbstraction { return response as string; } - async getBillingStatus(id: string): Promise<OrganizationBillingStatusResponse> { + async getOrganizationBillingStatus(id: string): Promise<OrganizationBillingStatusResponse> { const r = await this.apiService.send( "GET", "/organizations/" + id + "/billing-status", @@ -90,19 +97,6 @@ export class BillingApiService implements BillingApiServiceAbstraction { return new OrganizationBillingMetadataResponse(r); } - async getOrganizationSubscription( - organizationId: string, - ): Promise<OrganizationSubscriptionResponse> { - const r = await this.apiService.send( - "GET", - "/organizations/" + organizationId + "/subscription", - null, - true, - true, - ); - return new OrganizationSubscriptionResponse(r); - } - async getPlans(): Promise<ListResponse<PlanResponse>> { const r = await this.apiService.send("GET", "/plans", null, false, true); return new ListResponse(r, PlanResponse); @@ -119,40 +113,55 @@ export class BillingApiService implements BillingApiServiceAbstraction { return response as string; } + async getProviderClientOrganizations( + providerId: string, + ): Promise<ListResponse<ProviderOrganizationOrganizationDetailsResponse>> { + const response = await this.execute(() => + this.apiService.send("GET", "/providers/" + providerId + "/organizations", null, true, true), + ); + return new ListResponse(response, ProviderOrganizationOrganizationDetailsResponse); + } + async getProviderInvoices(providerId: string): Promise<InvoicesResponse> { - const response = await this.apiService.send( - "GET", - "/providers/" + providerId + "/billing/invoices", - null, - true, - true, + const response = await this.execute(() => + this.apiService.send( + "GET", + "/providers/" + providerId + "/billing/invoices", + null, + true, + true, + ), ); return new InvoicesResponse(response); } async getProviderPaymentInformation(providerId: string): Promise<PaymentInformationResponse> { - const response = await this.apiService.send( - "GET", - "/providers/" + providerId + "/billing/payment-information", - null, - true, - true, + const response = await this.execute(() => + this.apiService.send( + "GET", + "/providers/" + providerId + "/billing/payment-information", + null, + true, + true, + ), ); return new PaymentInformationResponse(response); } async getProviderSubscription(providerId: string): Promise<ProviderSubscriptionResponse> { - const r = await this.apiService.send( - "GET", - "/providers/" + providerId + "/billing/subscription", - null, - true, - true, + const response = await this.execute(() => + this.apiService.send( + "GET", + "/providers/" + providerId + "/billing/subscription", + null, + true, + true, + ), ); - return new ProviderSubscriptionResponse(r); + return new ProviderSubscriptionResponse(response); } - async updateClientOrganization( + async updateProviderClientOrganization( providerId: string, organizationId: string, request: UpdateClientOrganizationRequest, @@ -198,4 +207,20 @@ export class BillingApiService implements BillingApiServiceAbstraction { false, ); } + + private async execute(request: () => Promise<any>): Promise<any> { + try { + return await request(); + } catch (error) { + this.logService.error(error); + if (error instanceof ErrorResponse) { + this.toastService.showToast({ + variant: "error", + title: null, + message: error.getSingleMessage(), + }); + } + throw error; + } + } } diff --git a/libs/common/src/billing/services/payment-method-warnings.service.spec.ts b/libs/common/src/billing/services/payment-method-warnings.service.spec.ts index 55e72d3d721..6e37821ef50 100644 --- a/libs/common/src/billing/services/payment-method-warnings.service.spec.ts +++ b/libs/common/src/billing/services/payment-method-warnings.service.spec.ts @@ -113,13 +113,13 @@ describe("Payment Method Warnings Service", () => { }; activeUserState.nextState(state); await paymentMethodWarningsService.update(organizationId); - expect(billingApiService.getBillingStatus).not.toHaveBeenCalled(); + expect(billingApiService.getOrganizationBillingStatus).not.toHaveBeenCalled(); }); it("Retrieves the billing status from the API and uses it to update the state if the state is null", async () => { const organizationId = "1"; activeUserState.nextState(null); - billingApiService.getBillingStatus.mockResolvedValue( + billingApiService.getOrganizationBillingStatus.mockResolvedValue( getBillingStatusResponse(organizationId), ); await paymentMethodWarningsService.update(organizationId); @@ -131,7 +131,7 @@ describe("Payment Method Warnings Service", () => { savedAt: any(), }, }); - expect(billingApiService.getBillingStatus).toHaveBeenCalledTimes(1); + expect(billingApiService.getOrganizationBillingStatus).toHaveBeenCalledTimes(1); }); it("Retrieves the billing status from the API and uses it to update the state if the stored warning is null", async () => { @@ -139,7 +139,7 @@ describe("Payment Method Warnings Service", () => { activeUserState.nextState({ [organizationId]: null, }); - billingApiService.getBillingStatus.mockResolvedValue( + billingApiService.getOrganizationBillingStatus.mockResolvedValue( getBillingStatusResponse(organizationId), ); await paymentMethodWarningsService.update(organizationId); @@ -151,7 +151,7 @@ describe("Payment Method Warnings Service", () => { savedAt: any(), }, }); - expect(billingApiService.getBillingStatus).toHaveBeenCalledTimes(1); + expect(billingApiService.getOrganizationBillingStatus).toHaveBeenCalledTimes(1); }); it("Retrieves the billing status from the API and uses it to update the state if the stored warning is older than a week", async () => { @@ -164,7 +164,7 @@ describe("Payment Method Warnings Service", () => { savedAt: getPastDate(10), }, }); - billingApiService.getBillingStatus.mockResolvedValue( + billingApiService.getOrganizationBillingStatus.mockResolvedValue( new OrganizationBillingStatusResponse({ OrganizationId: organizationId, OrganizationName: "Teams Organization", @@ -180,7 +180,7 @@ describe("Payment Method Warnings Service", () => { savedAt: any(), }, }); - expect(billingApiService.getBillingStatus).toHaveBeenCalledTimes(1); + expect(billingApiService.getOrganizationBillingStatus).toHaveBeenCalledTimes(1); }); }); }); diff --git a/libs/common/src/billing/services/payment-method-warnings.service.ts b/libs/common/src/billing/services/payment-method-warnings.service.ts index ad9cd026181..0dad48bb85f 100644 --- a/libs/common/src/billing/services/payment-method-warnings.service.ts +++ b/libs/common/src/billing/services/payment-method-warnings.service.ts @@ -52,7 +52,7 @@ export class PaymentMethodWarningsService implements PaymentMethodWarningsServic ); if (!warning || warning.savedAt < this.getOneWeekAgo()) { const { organizationName, risksSubscriptionFailure } = - await this.billingApiService.getBillingStatus(organizationId); + await this.billingApiService.getOrganizationBillingStatus(organizationId); await this.paymentMethodWarningsState.update((state) => { state ??= {}; state[organizationId] = {