From 4a8b44b662b0bc4e33ec8f87ae5cc0de9b0e73b4 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Wed, 26 Jun 2024 05:45:03 +1000 Subject: [PATCH 001/130] Add eslint rule prohibiting Bitwarden-licensed imports in OSS code (#9801) --- .eslintrc.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.eslintrc.json b/.eslintrc.json index 72b65d361d0..cd1a22c5cca 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -324,6 +324,26 @@ "rules": { "no-restricted-imports": ["error", { "patterns": ["@bitwarden/bit-common/*", "src/**/*"] }] } + }, + { + "files": ["apps/**/*.ts"], + "rules": { + // Catches static imports + "no-restricted-imports": [ + "error", + { + "patterns": ["biwarden_license/**", "@bitwarden/bit-common/*", "@bitwarden/bit-web/*"] + } + ], + // Catches dynamic imports, e.g. in routing modules where modules are lazy-loaded + "no-restricted-syntax": [ + "error", + { + "message": "Don't import Bitwarden licensed code into OSS code.", + "selector": "ImportExpression > Literal.source[value=/.*(bitwarden_license|bit-common|bit-web).*/]" + } + ] + } } ] } From 00801f95cec7b5dca8cbee0f0b59752f5d5021ff Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Wed, 26 Jun 2024 05:54:38 +1000 Subject: [PATCH 002/130] CLI device approvals - Use single deny endpoint (#9763) --- .../admin-console/device-approval/approve.command.ts | 2 +- .../admin-console/device-approval/deny.command.ts | 12 +++++++++--- .../organization-auth-request-api.service.ts | 10 ++++++++++ .../organization-auth-request.service.ts | 4 ++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/bitwarden_license/bit-cli/src/admin-console/device-approval/approve.command.ts b/bitwarden_license/bit-cli/src/admin-console/device-approval/approve.command.ts index 918bd077b05..dc6a6d8e906 100644 --- a/bitwarden_license/bit-cli/src/admin-console/device-approval/approve.command.ts +++ b/bitwarden_license/bit-cli/src/admin-console/device-approval/approve.command.ts @@ -43,7 +43,7 @@ export class ApproveCommand { const request = pendingRequests.find((r) => r.id == id); if (request == null) { - return Response.error("Invalid request id"); + return Response.error("The request id is invalid."); } await this.organizationAuthRequestService.approvePendingRequest(organizationId, request); diff --git a/bitwarden_license/bit-cli/src/admin-console/device-approval/deny.command.ts b/bitwarden_license/bit-cli/src/admin-console/device-approval/deny.command.ts index 3470baaa25e..cf2356b1950 100644 --- a/bitwarden_license/bit-cli/src/admin-console/device-approval/deny.command.ts +++ b/bitwarden_license/bit-cli/src/admin-console/device-approval/deny.command.ts @@ -38,10 +38,16 @@ export class DenyCommand { } try { - await this.organizationAuthRequestService.denyPendingRequests(organizationId, id); + await this.organizationAuthRequestService.denyPendingRequest(organizationId, id); return Response.success(); - } catch (e) { - return Response.error(e); + } catch (error) { + if (error?.statusCode === 404) { + return Response.error( + "The request id is invalid or you do not have permission to update it.", + ); + } + + return Response.error(error); } } diff --git a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request-api.service.ts b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request-api.service.ts index 3387b7d54ed..4995df79922 100644 --- a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request-api.service.ts +++ b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request-api.service.ts @@ -61,4 +61,14 @@ export class OrganizationAuthRequestApiService { false, ); } + + async denyPendingRequest(organizationId: string, requestId: string): Promise { + await this.apiService.send( + "POST", + `/organizations/${organizationId}/auth-requests/${requestId}`, + new AdminAuthRequestUpdateRequest(false), + true, + false, + ); + } } diff --git a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts index c35b91396d0..245baf7e722 100644 --- a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts +++ b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts @@ -85,6 +85,10 @@ export class OrganizationAuthRequestService { ); } + async denyPendingRequest(organizationId: string, requestId: string) { + await this.organizationAuthRequestApiService.denyPendingRequest(organizationId, requestId); + } + /** * Creates a copy of the user key that has been encrypted with the provided device's public key. * @param organizationId From 8df054cf5117f7d92cfc0048901d542c27eefae0 Mon Sep 17 00:00:00 2001 From: Will Martin Date: Tue, 25 Jun 2024 15:55:49 -0400 Subject: [PATCH 003/130] [CL-319] custom back action in popup header component (#9829) * expose FunctionReturningAwaitable from CL lib * expose backAction as input on popup header component --- .../popup/layout/popup-header.component.html | 2 +- .../popup/layout/popup-header.component.ts | 23 ++++++++++++++----- libs/components/src/index.ts | 2 +- libs/components/src/utils/index.ts | 2 ++ 4 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 libs/components/src/utils/index.ts diff --git a/apps/browser/src/platform/popup/layout/popup-header.component.html b/apps/browser/src/platform/popup/layout/popup-header.component.html index 55caf1b91e7..e866ba4e81f 100644 --- a/apps/browser/src/platform/popup/layout/popup-header.component.html +++ b/apps/browser/src/platform/popup/layout/popup-header.component.html @@ -9,7 +9,7 @@ *ngIf="showBackButton" [title]="'back' | i18n" [ariaLabel]="'back' | i18n" - (click)="back()" + [bitAction]="backAction" >

{{ pageTitle }}

diff --git a/apps/browser/src/platform/popup/layout/popup-header.component.ts b/apps/browser/src/platform/popup/layout/popup-header.component.ts index f2f8eb95af0..1b491ea881c 100644 --- a/apps/browser/src/platform/popup/layout/popup-header.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-header.component.ts @@ -3,13 +3,18 @@ import { CommonModule, Location } from "@angular/common"; import { Component, Input } from "@angular/core"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { IconButtonModule, TypographyModule } from "@bitwarden/components"; +import { + AsyncActionsModule, + FunctionReturningAwaitable, + IconButtonModule, + TypographyModule, +} from "@bitwarden/components"; @Component({ selector: "popup-header", templateUrl: "popup-header.component.html", standalone: true, - imports: [TypographyModule, CommonModule, IconButtonModule, JslibModule], + imports: [TypographyModule, CommonModule, IconButtonModule, JslibModule, AsyncActionsModule], }) export class PopupHeaderComponent { /** Display the back button, which uses Location.back() to go back one page in history */ @@ -26,9 +31,15 @@ export class PopupHeaderComponent { /** Title string that will be inserted as an h1 */ @Input({ required: true }) pageTitle: string; - constructor(private location: Location) {} - - back() { + /** + * Async action that occurs when clicking the back button + * + * If unset, will call `location.back()` + **/ + @Input() + backAction: FunctionReturningAwaitable = async () => { this.location.back(); - } + }; + + constructor(private location: Location) {} } diff --git a/libs/components/src/index.ts b/libs/components/src/index.ts index 9e9329b2158..6881d801e0f 100644 --- a/libs/components/src/index.ts +++ b/libs/components/src/index.ts @@ -35,4 +35,4 @@ export * from "./tabs"; export * from "./toast"; export * from "./toggle-group"; export * from "./typography"; -export * from "./utils/i18n-mock.service"; +export * from "./utils"; diff --git a/libs/components/src/utils/index.ts b/libs/components/src/utils/index.ts new file mode 100644 index 00000000000..afadd6b3b41 --- /dev/null +++ b/libs/components/src/utils/index.ts @@ -0,0 +1,2 @@ +export * from "./function-to-observable"; +export * from "./i18n-mock.service"; From 3f44eadb5f29ae48a90ac22d8ff5f12098fbb99a Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 25 Jun 2024 18:17:10 -0400 Subject: [PATCH 004/130] Translation settings should be persisted on web (#9581) Unfortunately we cannot migrate this data from session, as it is lost on tab closed. --- libs/common/src/platform/state/state-definitions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index f3427429430..e22763e6fb7 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -112,7 +112,7 @@ export const DESKTOP_SETTINGS_DISK = new StateDefinition("desktopSettings", "dis export const ENVIRONMENT_DISK = new StateDefinition("environment", "disk"); export const ENVIRONMENT_MEMORY = new StateDefinition("environment", "memory"); export const THEMING_DISK = new StateDefinition("theming", "disk", { web: "disk-local" }); -export const TRANSLATION_DISK = new StateDefinition("translation", "disk"); +export const TRANSLATION_DISK = new StateDefinition("translation", "disk", { web: "disk-local" }); // Secrets Manager From 93a57e6724abdf4d59d1663f8c5ad9659f2a910c Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Wed, 26 Jun 2024 11:26:50 +0200 Subject: [PATCH 005/130] Add optional altOptions to componentRouteSwap (#9821) --- libs/angular/src/utils/component-route-swap.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libs/angular/src/utils/component-route-swap.ts b/libs/angular/src/utils/component-route-swap.ts index 1a2db317d6a..1a45671d2be 100644 --- a/libs/angular/src/utils/component-route-swap.ts +++ b/libs/angular/src/utils/component-route-swap.ts @@ -26,27 +26,31 @@ import { Route, Routes } from "@angular/router"; * @param defaultComponent - The default component to render. * @param altComponent - The alternate component to render when the condition is met. * @param shouldSwapFn - The async function to determine if the alternate component should be rendered. - * @param options - The shared route options to apply to both components. + * @param options - The shared route options to apply to the default component, and to the alt component if altOptions is not provided. + * @param altOptions - The alt route options to apply to the alt component. */ export function componentRouteSwap( defaultComponent: Type, altComponent: Type, shouldSwapFn: () => Promise, options: Route, + altOptions?: Route, ): Routes { const defaultRoute = { ...options, component: defaultComponent, }; + const selectedAltOptions = altOptions ?? options; + const altRoute: Route = { - ...options, + ...selectedAltOptions, component: altComponent, canMatch: [ async () => { return await shouldSwapFn(); }, - ...(options.canMatch ?? []), + ...(selectedAltOptions.canMatch ?? []), ], }; From 679c25b082db9e01b6f5d37b6adf4fc379acac81 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:08:25 -0400 Subject: [PATCH 006/130] Combined subscription and payment method pages in provider portal (#9828) --- .../providers/providers-layout.component.html | 1 - .../providers/providers-routing.module.ts | 9 -- .../providers/providers.module.ts | 4 +- ...ovider-subscription-status.component.html} | 11 +- ...provider-subscription-status.component.ts} | 65 ++------- .../provider-subscription.component.html | 131 +++++++++++------- .../provider-subscription.component.ts | 33 ++++- .../provider-subscription-response.ts | 31 +++-- .../subscription-suspension.response.ts | 15 ++ 9 files changed, 160 insertions(+), 140 deletions(-) rename bitwarden_license/bit-web/src/app/billing/providers/subscription/{subscription-status.component.html => provider-subscription-status.component.html} (71%) rename bitwarden_license/bit-web/src/app/billing/providers/subscription/{subscription-status.component.ts => provider-subscription-status.component.ts} (68%) create mode 100644 libs/common/src/billing/models/response/subscription-suspension.response.ts diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html index 3bd50539948..5a46b49f24e 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html @@ -31,7 +31,6 @@ *ngIf="canAccessBilling$ | async" > -

{{ data.callout.body }}

-
{{ "billingPlan" | i18n }}
@@ -18,7 +9,7 @@
{{ data.status.label }}
- {{ displayedStatus }} + {{ data.status.value }}
diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/subscription-status.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.ts similarity index 68% rename from bitwarden_license/bit-web/src/app/billing/providers/subscription/subscription-status.component.ts rename to bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.ts index 91cdef10aca..c3ad875136e 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/subscription-status.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription-status.component.ts @@ -1,5 +1,5 @@ import { DatePipe } from "@angular/common"; -import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { Component, Input } from "@angular/core"; import { ProviderSubscriptionResponse } from "@bitwarden/common/billing/models/response/provider-subscription-response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -17,47 +17,29 @@ type ComponentData = { severity: "danger" | "warning"; header: string; body: string; - showReinstatementButton: boolean; }; }; @Component({ - selector: "app-subscription-status", - templateUrl: "subscription-status.component.html", + selector: "app-provider-subscription-status", + templateUrl: "provider-subscription-status.component.html", }) -export class SubscriptionStatusComponent { - @Input({ required: true }) providerSubscriptionResponse: ProviderSubscriptionResponse; - @Output() reinstatementRequested = new EventEmitter(); +export class ProviderSubscriptionStatusComponent { + @Input({ required: true }) subscription: ProviderSubscriptionResponse; constructor( private datePipe: DatePipe, private i18nService: I18nService, ) {} - get displayedStatus(): string { - return this.data.status.value; - } - - get planName() { - return this.providerSubscriptionResponse.plans[0]; - } - get status(): string { if (this.subscription.cancelAt && this.subscription.status === "active") { - this.subscription.status = "pending_cancellation"; + return "pending_cancellation"; } return this.subscription.status; } - get isExpired() { - return this.subscription.status !== "active"; - } - - get subscription() { - return this.providerSubscriptionResponse; - } - get data(): ComponentData { const defaultStatusLabel = this.i18nService.t("status"); @@ -66,21 +48,6 @@ export class SubscriptionStatusComponent { const cancellationDateLabel = this.i18nService.t("cancellationDate"); switch (this.status) { - case "free": { - return {}; - } - case "trialing": { - return { - status: { - label: defaultStatusLabel, - value: this.i18nService.t("trial"), - }, - date: { - label: nextChargeDateLabel, - value: this.subscription.currentPeriodEndDate.toDateString(), - }, - }; - } case "active": { return { status: { @@ -89,26 +56,26 @@ export class SubscriptionStatusComponent { }, date: { label: nextChargeDateLabel, - value: this.subscription.currentPeriodEndDate.toDateString(), + value: this.subscription.currentPeriodEndDate, }, }; } case "past_due": { const pastDueText = this.i18nService.t("pastDue"); const suspensionDate = this.datePipe.transform( - this.subscription.suspensionDate, + this.subscription.suspension.suspensionDate, "mediumDate", ); const calloutBody = this.subscription.collectionMethod === "charge_automatically" ? this.i18nService.t( "pastDueWarningForChargeAutomatically", - this.subscription.gracePeriod, + this.subscription.suspension.gracePeriod, suspensionDate, ) : this.i18nService.t( "pastDueWarningForSendInvoice", - this.subscription.gracePeriod, + this.subscription.suspension.gracePeriod, suspensionDate, ); return { @@ -118,13 +85,12 @@ export class SubscriptionStatusComponent { }, date: { label: subscriptionExpiredDateLabel, - value: this.subscription.unpaidPeriodEndDate, + value: this.subscription.suspension.unpaidPeriodEndDate, }, callout: { severity: "warning", header: pastDueText, body: calloutBody, - showReinstatementButton: false, }, }; } @@ -136,13 +102,12 @@ export class SubscriptionStatusComponent { }, date: { label: subscriptionExpiredDateLabel, - value: this.subscription.currentPeriodEndDate.toDateString(), + value: this.subscription.suspension.unpaidPeriodEndDate, }, callout: { severity: "danger", header: this.i18nService.t("unpaidInvoice"), body: this.i18nService.t("toReactivateYourSubscription"), - showReinstatementButton: false, }, }; } @@ -163,7 +128,6 @@ export class SubscriptionStatusComponent { body: this.i18nService.t("subscriptionPendingCanceled") + this.i18nService.t("providerReinstate"), - showReinstatementButton: false, }, }; } @@ -177,18 +141,15 @@ export class SubscriptionStatusComponent { }, date: { label: cancellationDateLabel, - value: this.subscription.currentPeriodEndDate.toDateString(), + value: this.subscription.currentPeriodEndDate, }, callout: { severity: "danger", header: canceledText, body: this.i18nService.t("subscriptionCanceled"), - showReinstatementButton: false, }, }; } } } - - requestReinstatement = () => this.reinstatementRequested.emit(); } 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 47f8aa375c6..d4474953872 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 @@ -4,58 +4,85 @@ {{ "loading" | i18n }} - - -
- {{ "details" | i18n }}  {{ "providerDiscount" | i18n: subscription.discountPercentage }} - - - - - - - {{ getFormattedPlanName(i.planName) }} {{ "orgSeats" | i18n }} ({{ - i.cadence.toLowerCase() - }}) {{ "×" }}{{ getFormattedSeatCount(i.seatMinimum, i.purchasedSeats) }} - @ - {{ - getFormattedCost( - i.cost, - i.seatMinimum, - i.purchasedSeats, - subscription.discountPercentage - ) | currency: "$" - }} - - - {{ ((100 - subscription.discountPercentage) / 100) * i.cost | currency: "$" }} /{{ - "month" | i18n - }} -
- - {{ i.cost | currency: "$" }} /{{ "month" | i18n }} - -
- - + + + +
+ {{ "details" | i18n }}  {{ "providerDiscount" | i18n: subscription.discountPercentage }} + + + + + + + {{ getFormattedPlanName(i.planName) }} {{ "orgSeats" | i18n }} ({{ + i.cadence.toLowerCase() + }}) {{ "×" }}{{ getFormattedSeatCount(i.seatMinimum, i.purchasedSeats) }} + @ + {{ + getFormattedCost( + i.cost, + i.seatMinimum, + i.purchasedSeats, + subscription.discountPercentage + ) | currency: "$" + }} + + + {{ ((100 - subscription.discountPercentage) / 100) * i.cost | currency: "$" }} /{{ + "month" | i18n + }} +
+ + {{ i.cost | currency: "$" }} /{{ "month" | i18n }} + +
+ + - - - - Total: {{ totalCost | currency: "$" }} /{{ - "month" | i18n - }} - - -
-
-
-
+ + + + Total: {{ totalCost | currency: "$" }} /{{ + "month" | i18n + }} + + +
+
+
+
+
+ + +

+ {{ "accountCredit" | i18n }} +

+

{{ subscription.accountCredit | currency: "$" }}

+

{{ "creditAppliedDesc" | i18n }}

+ +
+ + +

{{ "taxInformation" | i18n }}

+

{{ "taxInformationDesc" | i18n }}

+ +
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 ca405747bf1..d582ad071fc 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,19 +2,25 @@ 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"; import { ProviderPlanResponse, 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"; @Component({ selector: "app-provider-subscription", templateUrl: "./provider-subscription.component.html", }) export class ProviderSubscriptionComponent { - subscription: ProviderSubscriptionResponse; providerId: string; + subscription: ProviderSubscriptionResponse; + firstLoaded = false; loading: boolean; private destroy$ = new Subject(); @@ -23,7 +29,10 @@ export class ProviderSubscriptionComponent { constructor( private billingApiService: BillingApiServiceAbstraction, + private dialogService: DialogService, + private i18nService: I18nService, private route: ActivatedRoute, + private toastService: ToastService, ) {} async ngOnInit() { @@ -54,6 +63,23 @@ 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); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("updatedTaxInformation"), + }); + }; + getFormattedCost( cost: number, seatMinimum: number, @@ -61,8 +87,7 @@ export class ProviderSubscriptionComponent { discountPercentage: number, ): number { const costPerSeat = cost / (seatMinimum + purchasedSeats); - const discountedCost = costPerSeat - (costPerSeat * discountPercentage) / 100; - return discountedCost; + return costPerSeat - (costPerSeat * discountPercentage) / 100; } getFormattedPlanName(planName: string): string { @@ -83,4 +108,6 @@ export class ProviderSubscriptionComponent { this.destroy$.next(); this.destroy$.complete(); } + + protected readonly TaxInformation = TaxInformation; } diff --git a/libs/common/src/billing/models/response/provider-subscription-response.ts b/libs/common/src/billing/models/response/provider-subscription-response.ts index 4986914cc0b..2dc9d4281de 100644 --- a/libs/common/src/billing/models/response/provider-subscription-response.ts +++ b/libs/common/src/billing/models/response/provider-subscription-response.ts @@ -1,29 +1,38 @@ +import { SubscriptionSuspensionResponse } from "@bitwarden/common/billing/models/response/subscription-suspension.response"; +import { TaxInfoResponse } from "@bitwarden/common/billing/models/response/tax-info.response"; + import { BaseResponse } from "../../../models/response/base.response"; export class ProviderSubscriptionResponse extends BaseResponse { status: string; - currentPeriodEndDate: Date; + currentPeriodEndDate: string; discountPercentage?: number | null; - plans: ProviderPlanResponse[] = []; collectionMethod: string; - unpaidPeriodEndDate?: string; - gracePeriod?: number | null; - suspensionDate?: string; + plans: ProviderPlanResponse[] = []; + accountCredit: number; + taxInformation?: TaxInfoResponse; cancelAt?: string; + suspension?: SubscriptionSuspensionResponse; constructor(response: any) { super(response); this.status = this.getResponseProperty("status"); - this.currentPeriodEndDate = new Date(this.getResponseProperty("currentPeriodEndDate")); + this.currentPeriodEndDate = this.getResponseProperty("currentPeriodEndDate"); this.discountPercentage = this.getResponseProperty("discountPercentage"); this.collectionMethod = this.getResponseProperty("collectionMethod"); - this.unpaidPeriodEndDate = this.getResponseProperty("unpaidPeriodEndDate"); - this.gracePeriod = this.getResponseProperty("gracePeriod"); - this.suspensionDate = this.getResponseProperty("suspensionDate"); - this.cancelAt = this.getResponseProperty("cancelAt"); const plans = this.getResponseProperty("plans"); if (plans != null) { - this.plans = plans.map((i: any) => new ProviderPlanResponse(i)); + this.plans = plans.map((plan: any) => new ProviderPlanResponse(plan)); + } + this.accountCredit = this.getResponseProperty("accountCredit"); + const taxInformation = this.getResponseProperty("taxInformation"); + if (taxInformation != null) { + this.taxInformation = new TaxInfoResponse(taxInformation); + } + this.cancelAt = this.getResponseProperty("cancelAt"); + const suspension = this.getResponseProperty("suspension"); + if (suspension != null) { + this.suspension = new SubscriptionSuspensionResponse(suspension); } } } diff --git a/libs/common/src/billing/models/response/subscription-suspension.response.ts b/libs/common/src/billing/models/response/subscription-suspension.response.ts new file mode 100644 index 00000000000..418e1c443c8 --- /dev/null +++ b/libs/common/src/billing/models/response/subscription-suspension.response.ts @@ -0,0 +1,15 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +export class SubscriptionSuspensionResponse extends BaseResponse { + suspensionDate: string; + unpaidPeriodEndDate: string; + gracePeriod: number; + + constructor(response: any) { + super(response); + + this.suspensionDate = this.getResponseProperty("suspensionDate"); + this.unpaidPeriodEndDate = this.getResponseProperty("unpaidPeriodEndDate"); + this.gracePeriod = this.getResponseProperty("gracePeriod"); + } +} From dbc6f1c840aa7c27a75a1f79d214f6ec89c7c04e Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:30:37 -0400 Subject: [PATCH 007/130] Add description to billing history, update invoice table and report name (#9777) --- apps/web/src/locales/en/messages.json | 12 ++++++- .../provider-billing-history.component.html | 1 + .../provider-billing-history.component.ts | 2 +- .../invoices/invoices.component.html | 33 +++---------------- libs/angular/src/jslib.module.ts | 2 ++ .../models/response/invoices.response.ts | 2 -- 6 files changed, 19 insertions(+), 33 deletions(-) diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index d649797750e..7a129f04e61 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8469,6 +8469,16 @@ }, "uncollectible": { "message": "Uncollectible", - "description": "The status of an invoice." + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.html b/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.html index 5d3bc2fff9a..95500016d40 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.html @@ -1,6 +1,7 @@

{{ "invoices" | i18n }}

+

{{ "billingHistoryDescription" | i18n }}

{ const date = this.datePipe.transform(invoice.date, "yyyyMMdd"); - return `bitwarden_provider_${date}_${invoice.number}`; + return `bitwarden_provider-billing-history_${date}_${invoice.number}`; }; getInvoices = async () => await this.billingApiService.getProviderInvoices(this.providerId); diff --git a/libs/angular/src/billing/components/invoices/invoices.component.html b/libs/angular/src/billing/components/invoices/invoices.component.html index 2ce01aa50b9..0fbc27c678e 100644 --- a/libs/angular/src/billing/components/invoices/invoices.component.html +++ b/libs/angular/src/billing/components/invoices/invoices.component.html @@ -13,6 +13,7 @@ {{ "invoice" | i18n }} {{ "total" | i18n }} {{ "status" | i18n }} + {{ "clientDetails" | i18n }} @@ -47,35 +48,9 @@ - - - - - {{ "viewInvoice" | i18n }} - - - + diff --git a/libs/angular/src/jslib.module.ts b/libs/angular/src/jslib.module.ts index 59d50ee389a..b03dde3a34a 100644 --- a/libs/angular/src/jslib.module.ts +++ b/libs/angular/src/jslib.module.ts @@ -17,6 +17,7 @@ import { DialogModule, FormFieldModule, IconButtonModule, + LinkModule, MenuModule, RadioButtonModule, SelectModule, @@ -73,6 +74,7 @@ import { IconComponent } from "./vault/components/icon.component"; TableModule, MenuModule, IconButtonModule, + LinkModule, ], declarations: [ A11yInvalidDirective, diff --git a/libs/common/src/billing/models/response/invoices.response.ts b/libs/common/src/billing/models/response/invoices.response.ts index 2725d083be7..bf797ba42d6 100644 --- a/libs/common/src/billing/models/response/invoices.response.ts +++ b/libs/common/src/billing/models/response/invoices.response.ts @@ -20,7 +20,6 @@ export class InvoiceResponse extends BaseResponse { status: string; dueDate: string; url: string; - pdfUrl: string; constructor(response: any) { super(response); @@ -31,6 +30,5 @@ export class InvoiceResponse extends BaseResponse { this.status = this.getResponseProperty("Status"); this.dueDate = this.getResponseProperty("DueDate"); this.url = this.getResponseProperty("Url"); - this.pdfUrl = this.getResponseProperty("PdfUrl"); } } From c85429ab4f719fb37658e11c7652fc3d70a7e261 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:33:26 -0400 Subject: [PATCH 008/130] Make provider discount dynamic in provider portal (#9831) --- .../clients/create-client-dialog.component.html | 4 +++- .../clients/create-client-dialog.component.ts | 13 +++++++++---- .../provider-subscription.component.html | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html index 72067253011..8a22e964d43 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.html @@ -7,7 +7,9 @@

{{ "createNewClientToManageAsProvider" | i18n }}

{{ "selectAPlan" | i18n }} - {{ "thirtyFivePercentDiscount" | i18n }} + {{ + "providerDiscount" | i18n: this.discountPercentage + }}
diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts index 8c013674bdb..987b7cc6982 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts @@ -42,6 +42,7 @@ type PlanCard = { templateUrl: "./create-client-dialog.component.html", }) export class CreateClientDialogComponent implements OnInit { + protected discountPercentage: number; protected formGroup = new FormGroup({ clientOwnerEmail: new FormControl("", [Validators.required, Validators.email]), organizationName: new FormControl("", [Validators.required]), @@ -96,27 +97,31 @@ export class CreateClientDialogComponent implements OnInit { } async ngOnInit(): Promise { - const subscription = await this.billingApiService.getProviderSubscription( + const response = await this.billingApiService.getProviderSubscription( this.dialogParams.providerId, ); - this.providerPlans = subscription?.plans ?? []; + + this.providerPlans = response?.plans ?? []; const teamsPlan = this.dialogParams.plans.find((plan) => plan.type === PlanType.TeamsMonthly); const enterprisePlan = this.dialogParams.plans.find( (plan) => plan.type === PlanType.EnterpriseMonthly, ); + this.discountPercentage = response.discountPercentage; + const discountFactor = this.discountPercentage ? (100 - this.discountPercentage) / 100 : 1; + this.planCards = [ { name: this.i18nService.t("planNameTeams"), - cost: teamsPlan.PasswordManager.providerPortalSeatPrice * 0.65, // 35% off for MSPs, + cost: teamsPlan.PasswordManager.providerPortalSeatPrice * discountFactor, type: teamsPlan.type, plan: teamsPlan, selected: true, }, { name: this.i18nService.t("planNameEnterprise"), - cost: enterprisePlan.PasswordManager.providerPortalSeatPrice * 0.65, // 35% off for MSPs, + cost: enterprisePlan.PasswordManager.providerPortalSeatPrice * discountFactor, type: enterprisePlan.type, plan: enterprisePlan, selected: false, 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 d4474953872..0aaa3cc03ae 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 @@ -41,7 +41,7 @@ {{ ((100 - subscription.discountPercentage) / 100) * i.cost | currency: "$" }} /{{ "month" | i18n }} -
+
{{ i.cost | currency: "$" }} /{{ "month" | i18n }} From 5e9e095b404c8a678cac872904960ef9a39eac41 Mon Sep 17 00:00:00 2001 From: KiruthigaManivannan <162679756+KiruthigaManivannan@users.noreply.github.com> Date: Wed, 26 Jun 2024 19:36:25 +0530 Subject: [PATCH 009/130] PM-5022 Migrate Payment Method component (#8397) * PM-5022 Migrated Payment Method component * PM-5022 Addressed review comments * PM-5022 Addressed review comments on CSS * PM-5022 Addressed the css comment and fixed build issues * PM-5022 Changed app-callout to bit-callout --------- Co-authored-by: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> --- .../shared/payment-method.component.html | 160 ++++++++---------- .../shared/payment-method.component.ts | 43 ++--- 2 files changed, 84 insertions(+), 119 deletions(-) diff --git a/apps/web/src/app/billing/shared/payment-method.component.html b/apps/web/src/app/billing/shared/payment-method.component.html index 2ac9233b5bb..495785af45f 100644 --- a/apps/web/src/app/billing/shared/payment-method.component.html +++ b/apps/web/src/app/billing/shared/payment-method.component.html @@ -3,7 +3,7 @@ type="button" bitButton buttonType="secondary" - (click)="load()" + [bitAction]="load" class="tw-ml-auto" *ngIf="firstLoaded" [disabled]="loading" @@ -14,115 +14,93 @@ -
- -

{{ "paymentMethod" | i18n }}

-
+ +

{{ "paymentMethod" | i18n }}

- {{ "loading" | i18n }} + {{ "loading" | i18n }} -

{{ (isCreditBalance ? "accountCredit" : "accountBalance") | i18n }}

-

- {{ creditOrBalance | currency: "$" }} -

-

{{ "creditAppliedDesc" | i18n }}

- -

{{ "paymentMethod" | i18n }}

-

{{ "noPaymentMethod" | i18n }}

- - -

{{ "verifyBankAccountDesc" | i18n }} {{ "verifyBankAccountFailureWarning" | i18n }}

-
+

+ {{ (isCreditBalance ? "accountCredit" : "accountBalance") | i18n }} +

+

{{ creditOrBalance | currency: "$" }}

+

{{ "creditAppliedDesc" | i18n }}

+ + + +

{{ "paymentMethod" | i18n }}

+

{{ "noPaymentMethod" | i18n }}

+ + - - {{ "amountX" | i18n: "1" }} - - $0. - - - {{ "amountX" | i18n: "2" }} - - $0. - - - -
-

- - {{ paymentSource.description }} + + {{ "amountX" | i18n: "1" }} + + $0. + + + {{ "amountX" | i18n: "2" }} + + $0. + + + + +

+ + {{ paymentSource.description }} +

+
+ +

+ {{ "paymentChargedWithUnpaidSubscription" | i18n }}

-
- -

{{ "paymentChargedWithUnpaidSubscription" | i18n }}

- -

{{ "taxInformation" | i18n }}

-

{{ "taxInformationDesc" | i18n }}

+ + +

{{ "taxInformation" | i18n }}

+

{{ "taxInformationDesc" | i18n }}

- {{ "loading" | i18n }} + {{ "loading" | i18n }}
-
+ -
-
+
diff --git a/apps/web/src/app/billing/shared/payment-method.component.ts b/apps/web/src/app/billing/shared/payment-method.component.ts index 967bff6d1ab..eacc0b47390 100644 --- a/apps/web/src/app/billing/shared/payment-method.component.ts +++ b/apps/web/src/app/billing/shared/payment-method.component.ts @@ -38,9 +38,6 @@ export class PaymentMethodComponent implements OnInit { organizationId: string; isUnpaid = false; - verifyBankPromise: Promise; - taxFormPromise: Promise; - verifyBankForm = this.formBuilder.group({ amount1: new FormControl(null, [ Validators.required, @@ -54,6 +51,8 @@ export class PaymentMethodComponent implements OnInit { ]), }); + taxForm = this.formBuilder.group({}); + constructor( protected apiService: ApiService, protected organizationApiService: OrganizationApiServiceAbstraction, @@ -83,7 +82,7 @@ export class PaymentMethodComponent implements OnInit { }); } - async load() { + load = async () => { if (this.loading) { return; } @@ -109,7 +108,7 @@ export class PaymentMethodComponent implements OnInit { this.isUnpaid = this.subscription?.status === "unpaid" ?? false; this.loading = false; - } + }; addCredit = async () => { const dialogRef = openAddCreditDialog(this.dialogService, { @@ -136,35 +135,23 @@ export class PaymentMethodComponent implements OnInit { } }; - async verifyBank() { + verifyBank = async () => { if (this.loading || !this.forOrganization) { return; } - try { - const request = new VerifyBankRequest(); - request.amount1 = this.verifyBankForm.value.amount1; - request.amount2 = this.verifyBankForm.value.amount2; - this.verifyBankPromise = this.organizationApiService.verifyBank(this.organizationId, request); - await this.verifyBankPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("verifiedBankAccount"), - ); - // 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.load(); - } catch (e) { - this.logService.error(e); - } - } + const request = new VerifyBankRequest(); + request.amount1 = this.verifyBankForm.value.amount1; + request.amount2 = this.verifyBankForm.value.amount2; + await this.organizationApiService.verifyBank(this.organizationId, request); + this.platformUtilsService.showToast("success", null, this.i18nService.t("verifiedBankAccount")); + await this.load(); + }; - async submitTaxInfo() { - this.taxFormPromise = this.taxInfo.submitTaxInfo(); - await this.taxFormPromise; + submitTaxInfo = async () => { + await this.taxInfo.submitTaxInfo(); this.platformUtilsService.showToast("success", null, this.i18nService.t("taxInfoUpdated")); - } + }; get isCreditBalance() { return this.billing == null || this.billing.balance <= 0; From ac2cfa2dfd5fd894e170e222401e8db59ae961de Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Wed, 26 Jun 2024 10:46:41 -0400 Subject: [PATCH 010/130] Add setuptools to mac pipeline (#9834) * Add setuptools to mac pipeline Mac runners have progressed above python 3.12, which removed `distutils`. We need to ensure it's installed for node-gyp compilations by installing the setuptools package. * Add missed mac build --- .github/workflows/build-desktop.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index bebf7b5646c..71ddd8584cf 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -464,6 +464,9 @@ jobs: cache-dependency-path: '**/package-lock.json' node-version: ${{ env._NODE_VERSION }} + - name: Set up Node-gyp + run: python3 -m pip install setuptools + - name: Rust shell: pwsh run: rustup target install aarch64-apple-darwin @@ -625,6 +628,9 @@ jobs: cache-dependency-path: '**/package-lock.json' node-version: ${{ env._NODE_VERSION }} + - name: Set up Node-gyp + run: python3 -m pip install setuptools + - name: Rust shell: pwsh run: rustup target install aarch64-apple-darwin @@ -831,6 +837,9 @@ jobs: cache-dependency-path: '**/package-lock.json' node-version: ${{ env._NODE_VERSION }} + - name: Set up Node-gyp + run: python3 -m pip install setuptools + - name: Rust shell: pwsh run: rustup target install aarch64-apple-darwin @@ -1028,6 +1037,9 @@ jobs: cache-dependency-path: '**/package-lock.json' node-version: ${{ env._NODE_VERSION }} + - name: Set up Node-gyp + run: python3 -m pip install setuptools + - name: Print environment run: | node --version From 1495b06736d5418afa1e7c41e610d9957e7c091b Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:52:55 +0200 Subject: [PATCH 011/130] Move send icons to @bitwarden/send-ui (#9840) Co-authored-by: Daniel James Smith --- apps/web/src/app/tools/send/access.component.ts | 4 ++-- apps/web/src/app/tools/send/send.component.ts | 4 ++-- libs/tools/send/send-ui/package.json | 3 ++- .../tools/send/send-ui/src}/icons/expired-send.icon.ts | 2 +- libs/tools/send/send-ui/src/icons/index.ts | 2 ++ .../tools/send/send-ui/src}/icons/no-send.icon.ts | 2 +- libs/tools/send/send-ui/src/index.ts | 1 + 7 files changed, 11 insertions(+), 7 deletions(-) rename {apps/web/src/app/tools/send => libs/tools/send/send-ui/src}/icons/expired-send.icon.ts (98%) create mode 100644 libs/tools/send/send-ui/src/icons/index.ts rename {apps/web/src/app/tools/send => libs/tools/send/send-ui/src}/icons/no-send.icon.ts (98%) diff --git a/apps/web/src/app/tools/send/access.component.ts b/apps/web/src/app/tools/send/access.component.ts index 64e46b3ff53..cd6850c7856 100644 --- a/apps/web/src/app/tools/send/access.component.ts +++ b/apps/web/src/app/tools/send/access.component.ts @@ -18,10 +18,10 @@ import { SendAccessView } from "@bitwarden/common/tools/send/models/view/send-ac import { SEND_KDF_ITERATIONS } from "@bitwarden/common/tools/send/send-kdf"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { NoItemsModule, ToastService } from "@bitwarden/components"; +import { ExpiredSendIcon } from "@bitwarden/send-ui"; import { SharedModule } from "../../shared"; -import { ExpiredSend } from "./icons/expired-send.icon"; import { SendAccessFileComponent } from "./send-access-file.component"; import { SendAccessPasswordComponent } from "./send-access-password.component"; import { SendAccessTextComponent } from "./send-access-text.component"; @@ -51,7 +51,7 @@ export class AccessComponent implements OnInit { protected hideEmail = false; protected decKey: SymmetricCryptoKey; protected accessRequest: SendAccessRequest; - protected expiredSendIcon = ExpiredSend; + protected expiredSendIcon = ExpiredSendIcon; protected formGroup = this.formBuilder.group({}); diff --git a/apps/web/src/app/tools/send/send.component.ts b/apps/web/src/app/tools/send/send.component.ts index 56f7734ca14..dad09ef70ae 100644 --- a/apps/web/src/app/tools/send/send.component.ts +++ b/apps/web/src/app/tools/send/send.component.ts @@ -19,12 +19,12 @@ import { TableDataSource, ToastService, } from "@bitwarden/components"; +import { NoSendsIcon } from "@bitwarden/send-ui"; import { HeaderModule } from "../../layouts/header/header.module"; import { SharedModule } from "../../shared"; import { AddEditComponent } from "./add-edit.component"; -import { NoSend } from "./icons/no-send.icon"; const BroadcasterSubscriptionId = "SendComponent"; @@ -37,7 +37,7 @@ const BroadcasterSubscriptionId = "SendComponent"; export class SendComponent extends BaseSendComponent { @ViewChild("sendAddEdit", { read: ViewContainerRef, static: true }) sendAddEditModalRef: ViewContainerRef; - noItemIcon = NoSend; + noItemIcon = NoSendsIcon; override set filteredSends(filteredSends: SendView[]) { super.filteredSends = filteredSends; diff --git a/libs/tools/send/send-ui/package.json b/libs/tools/send/send-ui/package.json index 81bbbde4358..4ffa4db0bdb 100644 --- a/libs/tools/send/send-ui/package.json +++ b/libs/tools/send/send-ui/package.json @@ -18,6 +18,7 @@ "build:watch": "npm run clean && tsc -watch" }, "dependencies": { - "@bitwarden/common": "file:../../../common" + "@bitwarden/common": "file:../../../common", + "@bitwarden/components": "file:../../../components" } } diff --git a/apps/web/src/app/tools/send/icons/expired-send.icon.ts b/libs/tools/send/send-ui/src/icons/expired-send.icon.ts similarity index 98% rename from apps/web/src/app/tools/send/icons/expired-send.icon.ts rename to libs/tools/send/send-ui/src/icons/expired-send.icon.ts index 3ce0856a269..c699a544e7c 100644 --- a/apps/web/src/app/tools/send/icons/expired-send.icon.ts +++ b/libs/tools/send/send-ui/src/icons/expired-send.icon.ts @@ -1,6 +1,6 @@ import { svgIcon } from "@bitwarden/components"; -export const ExpiredSend = svgIcon` +export const ExpiredSendIcon = svgIcon` diff --git a/libs/tools/send/send-ui/src/icons/index.ts b/libs/tools/send/send-ui/src/icons/index.ts new file mode 100644 index 00000000000..a2428e56330 --- /dev/null +++ b/libs/tools/send/send-ui/src/icons/index.ts @@ -0,0 +1,2 @@ +export { NoSendsIcon } from "./no-send.icon"; +export { ExpiredSendIcon } from "./expired-send.icon"; diff --git a/apps/web/src/app/tools/send/icons/no-send.icon.ts b/libs/tools/send/send-ui/src/icons/no-send.icon.ts similarity index 98% rename from apps/web/src/app/tools/send/icons/no-send.icon.ts rename to libs/tools/send/send-ui/src/icons/no-send.icon.ts index f5494a4b3c3..f3d06d0cfd0 100644 --- a/apps/web/src/app/tools/send/icons/no-send.icon.ts +++ b/libs/tools/send/send-ui/src/icons/no-send.icon.ts @@ -1,6 +1,6 @@ import { svgIcon } from "@bitwarden/components"; -export const NoSend = svgIcon` +export const NoSendsIcon = svgIcon` diff --git a/libs/tools/send/send-ui/src/index.ts b/libs/tools/send/send-ui/src/index.ts index e69de29bb2d..6ef8d54d416 100644 --- a/libs/tools/send/send-ui/src/index.ts +++ b/libs/tools/send/send-ui/src/index.ts @@ -0,0 +1 @@ +export * from "./icons"; From 5a74371672baccf1198ac5087e16e53996e4a792 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:08:18 +0200 Subject: [PATCH 012/130] Create "new Send-button with type selection (#9842) Co-authored-by: Daniel James Smith --- libs/tools/send/send-ui/src/index.ts | 1 + .../new-send-dropdown.component.html | 14 +++++++++++ .../new-send-dropdown.component.ts | 23 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html create mode 100644 libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts diff --git a/libs/tools/send/send-ui/src/index.ts b/libs/tools/send/send-ui/src/index.ts index 6ef8d54d416..fc7c87449dd 100644 --- a/libs/tools/send/send-ui/src/index.ts +++ b/libs/tools/send/send-ui/src/index.ts @@ -1 +1,2 @@ export * from "./icons"; +export { NewSendDropdownComponent } from "./new-send-dropdown/new-send-dropdown.component"; diff --git a/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html new file mode 100644 index 00000000000..0766435e1ce --- /dev/null +++ b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html @@ -0,0 +1,14 @@ + + {{ "new" | i18n }} + + + + + {{ "sendTypeText" | i18n }} + + + + {{ "sendTypeFile" | i18n }} + + diff --git a/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts new file mode 100644 index 00000000000..1463b448a6a --- /dev/null +++ b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts @@ -0,0 +1,23 @@ +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; +import { Router, RouterLink } from "@angular/router"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; +import { ButtonModule, MenuModule } from "@bitwarden/components"; + +@Component({ + selector: "tools-new-send-dropdown", + templateUrl: "new-send-dropdown.component.html", + standalone: true, + imports: [JslibModule, CommonModule, ButtonModule, RouterLink, MenuModule], +}) +export class NewSendDropdownComponent { + sendType = SendType; + + constructor(private router: Router) {} + + newItemNavigate(type: SendType) { + void this.router.navigate(["/add-send"], { queryParams: { type: type, isNew: true } }); + } +} From 31e5337ecfedfcff87b2ab08e7acdddb19dccf00 Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:06:50 -0700 Subject: [PATCH 013/130] change orgId input to masterPasswordPolicyOptions (#9833) --- .../input-password.component.html | 4 +- .../input-password.component.ts | 33 ++++--------- .../angular/input-password/input-password.mdx | 4 +- .../input-password/input-password.stories.ts | 49 ++++++------------- .../input-password/password-input-result.ts | 9 ++++ 5 files changed, 37 insertions(+), 62 deletions(-) create mode 100644 libs/auth/src/angular/input-password/password-input-result.ts 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 e6c36914cfd..f2ad810e7bb 100644 --- a/libs/auth/src/angular/input-password/input-password.component.html +++ b/libs/auth/src/angular/input-password/input-password.component.html @@ -1,7 +1,7 @@
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 49d02361d49..a8220595481 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -3,17 +3,12 @@ import { ReactiveFormsModule, FormBuilder, Validators } from "@angular/forms"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -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 { - DEFAULT_KDF_CONFIG, - PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; +import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { MasterKey } from "@bitwarden/common/types/key"; import { AsyncActionsModule, ButtonModule, @@ -29,12 +24,7 @@ import { InputsFieldMatch } from "../../../../angular/src/auth/validators/inputs import { SharedModule } from "../../../../components/src/shared"; import { PasswordCalloutComponent } from "../password-callout/password-callout.component"; -export interface PasswordInputResult { - masterKey: MasterKey; - masterKeyHash: string; - kdfConfig: PBKDF2KdfConfig; - hint: string; -} +import { PasswordInputResult } from "./password-input-result"; @Component({ standalone: true, @@ -58,14 +48,13 @@ export class InputPasswordComponent implements OnInit { @Input({ required: true }) email: string; @Input() protected buttonText: string; - @Input() private orgId: string; + @Input() masterPasswordPolicyOptions: MasterPasswordPolicyOptions | null = null; private minHintLength = 0; protected maxHintLength = 50; protected minPasswordLength = Utils.minimumPasswordLength; protected minPasswordMsg = ""; - protected masterPasswordPolicy: MasterPasswordPolicyOptions; protected passwordStrengthResult: any; protected showErrorSummary = false; protected showPassword = false; @@ -106,18 +95,16 @@ export class InputPasswordComponent implements OnInit { private i18nService: I18nService, private policyService: PolicyService, private toastService: ToastService, - private policyApiService: PolicyApiServiceAbstraction, ) {} async ngOnInit() { - this.masterPasswordPolicy = await this.policyApiService.getMasterPasswordPolicyOptsForOrgUser( - this.orgId, - ); - - if (this.masterPasswordPolicy != null && this.masterPasswordPolicy.minLength > 0) { + if ( + this.masterPasswordPolicyOptions != null && + this.masterPasswordPolicyOptions.minLength > 0 + ) { this.minPasswordMsg = this.i18nService.t( "characterMinimum", - this.masterPasswordPolicy.minLength, + this.masterPasswordPolicyOptions.minLength, ); } else { this.minPasswordMsg = this.i18nService.t("characterMinimum", this.minPasswordLength); @@ -157,11 +144,11 @@ export class InputPasswordComponent implements OnInit { // Check if password meets org policy requirements if ( - this.masterPasswordPolicy != null && + this.masterPasswordPolicyOptions != null && !this.policyService.evaluateMasterPassword( this.passwordStrengthResult.score, password, - this.masterPasswordPolicy, + this.masterPasswordPolicyOptions, ) ) { this.toastService.showToast({ diff --git a/libs/auth/src/angular/input-password/input-password.mdx b/libs/auth/src/angular/input-password/input-password.mdx index d442ea02fc9..5110e2b3130 100644 --- a/libs/auth/src/angular/input-password/input-password.mdx +++ b/libs/auth/src/angular/input-password/input-password.mdx @@ -22,8 +22,8 @@ the parent component to act on those values as needed. `InputPasswordComponent` can create a master key. - `buttonText` (optional) - an `i18n` translated string that can be used as button text (default text is "Set master password"). -- `orgId` (optional) - used to retreive and enforce the master password policy requirements for an - org. +- `masterPasswordPolicyOptions` (optional) - used to display and enforce master password policy + requirements.
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 a0dee87b27f..feccd8ccba5 100644 --- a/libs/auth/src/angular/input-password/input-password.stories.ts +++ b/libs/auth/src/angular/input-password/input-password.stories.ts @@ -2,11 +2,9 @@ import { importProvidersFrom } from "@angular/core"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { action } from "@storybook/addon-actions"; import { Meta, StoryObj, applicationConfig } from "@storybook/angular"; -import { of } from "rxjs"; import { ZXCVBNResult } from "zxcvbn"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -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 { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -17,22 +15,10 @@ import { PreloadedEnglishI18nModule } from "../../../../../apps/web/src/app/core import { InputPasswordComponent } from "./input-password.component"; -const mockMasterPasswordPolicyOptions = { - minComplexity: 4, - minLength: 14, - requireUpper: true, - requireLower: true, - requireNumbers: true, - requireSpecial: true, -} as MasterPasswordPolicyOptions; - export default { title: "Auth/Input Password", component: InputPasswordComponent, -} as Meta; - -const decorators = (options: { hasPolicy?: boolean }) => { - return [ + decorators: [ applicationConfig({ providers: [ importProvidersFrom(PreloadedEnglishI18nModule), @@ -56,18 +42,9 @@ const decorators = (options: { hasPolicy?: boolean }) => { openSimpleDialog: () => Promise.resolve(true), } as Partial, }, - { - provide: PolicyApiServiceAbstraction, - useValue: { - getMasterPasswordPolicyOptsForOrgUser: () => - options.hasPolicy ? mockMasterPasswordPolicyOptions : null, - } as Partial, - }, { provide: PolicyService, useValue: { - masterPasswordPolicyOptions$: () => - options.hasPolicy ? of(mockMasterPasswordPolicyOptions) : null, evaluateMasterPassword: (score) => { if (score < 4) { return false; @@ -81,7 +58,6 @@ const decorators = (options: { hasPolicy?: boolean }) => { useValue: { getPasswordStrength: (password) => { let score = 0; - if (password.length === 0) { score = null; } else if (password.length <= 4) { @@ -93,7 +69,6 @@ const decorators = (options: { hasPolicy?: boolean }) => { } else { score = 4; } - return { score } as ZXCVBNResult; }, } as Partial, @@ -106,8 +81,18 @@ const decorators = (options: { hasPolicy?: boolean }) => { }, ], }), - ]; -}; + ], + args: { + masterPasswordPolicyOptions: { + minComplexity: 4, + minLength: 14, + requireUpper: true, + requireLower: true, + requireNumbers: true, + requireSpecial: true, + } as MasterPasswordPolicyOptions, + }, +} as Meta; type Story = StoryObj; @@ -118,19 +103,13 @@ export const Default: Story = { `, }), - decorators: decorators({ - hasPolicy: false, - }), }; export const WithPolicy: Story = { render: (args) => ({ props: args, template: ` - + `, }), - decorators: decorators({ - hasPolicy: true, - }), }; diff --git a/libs/auth/src/angular/input-password/password-input-result.ts b/libs/auth/src/angular/input-password/password-input-result.ts new file mode 100644 index 00000000000..0a74b88a2e8 --- /dev/null +++ b/libs/auth/src/angular/input-password/password-input-result.ts @@ -0,0 +1,9 @@ +import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; +import { MasterKey } from "@bitwarden/common/types/key"; + +export interface PasswordInputResult { + masterKey: MasterKey; + masterKeyHash: string; + kdfConfig: PBKDF2KdfConfig; + hint: string; +} From b38629b4c96970add83d6dff82fa94db3f5b72a8 Mon Sep 17 00:00:00 2001 From: vinith-kovan <156108204+vinith-kovan@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:16:32 +0530 Subject: [PATCH 014/130] [AC-2411] migrate account component (#8854) * migrate account component * account component review comment addressed * account component review comment addressed --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --- .../settings/account.component.html | 9 +-- .../providers/settings/account.component.html | 50 +++++-------- .../providers/settings/account.component.ts | 74 +++++++++++-------- 3 files changed, 64 insertions(+), 69 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.html b/apps/web/src/app/admin-console/organizations/settings/account.component.html index e34972d36e6..f453546fcad 100644 --- a/apps/web/src/app/admin-console/organizations/settings/account.component.html +++ b/apps/web/src/app/admin-console/organizations/settings/account.component.html @@ -1,9 +1,8 @@ -
@@ -37,9 +36,9 @@

{{ "apiKey" | i18n }}

-

+

{{ "apiKeyDesc" | i18n }} - + {{ "learnMore" | i18n }}

@@ -56,7 +55,7 @@ [formGroup]="collectionManagementFormGroup" >

{{ "collectionManagement" | i18n }}

-

{{ "collectionManagementDesc" | i18n }}

+

{{ "collectionManagementDesc" | i18n }}

{{ "allowAdminAccessToAllCollectionItemsDesc" | i18n }} diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.html index 10f6d144252..a4e45877552 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.html @@ -2,51 +2,35 @@
- {{ "loading" | i18n }} + {{ "loading" | i18n }}
-
-
-
-
- + +
+
+ + {{ "providerName" | i18n }} + + + + {{ "billingEmail" | i18n }} -
-
- - -
+
-
+
- diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.ts index e2b8aeaffdf..01e863a826a 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/settings/account.component.ts @@ -1,5 +1,7 @@ -import { Component } from "@angular/core"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { FormBuilder, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; +import { Subject, switchMap, takeUntil } from "rxjs"; import { UserVerificationDialogComponent } from "@bitwarden/auth/angular"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; @@ -19,15 +21,18 @@ import { DialogService } from "@bitwarden/components"; templateUrl: "account.component.html", }) // eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class AccountComponent { +export class AccountComponent implements OnDestroy, OnInit { selfHosted = false; loading = true; provider: ProviderResponse; - formPromise: Promise; taxFormPromise: Promise; + private destroy$ = new Subject(); private providerId: string; - + protected formGroup = this.formBuilder.group({ + providerName: ["" as ProviderResponse["name"]], + providerBillingEmail: ["" as ProviderResponse["billingEmail"], Validators.email], + }); protected enableDeleteProvider$ = this.configService.getFeatureFlag$( FeatureFlag.EnableDeleteProvider, ); @@ -42,39 +47,47 @@ export class AccountComponent { private dialogService: DialogService, private configService: ConfigService, private providerApiService: ProviderApiServiceAbstraction, + private formBuilder: FormBuilder, private router: Router, ) {} async ngOnInit() { this.selfHosted = this.platformUtilsService.isSelfHost(); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.parent.parent.params.subscribe(async (params) => { - this.providerId = params.providerId; - try { - this.provider = await this.providerApiService.getProvider(this.providerId); - } catch (e) { - this.logService.error(`Handled exception: ${e}`); - } - }); - this.loading = false; + this.route.parent.parent.params + .pipe( + switchMap(async (params) => { + this.providerId = params.providerId; + try { + this.provider = await this.providerApiService.getProvider(this.providerId); + this.formGroup.patchValue({ + providerName: this.provider.name, + providerBillingEmail: this.provider.billingEmail, + }); + } catch (e) { + this.logService.error(`Handled exception: ${e}`); + } finally { + this.loading = false; + } + }), + takeUntil(this.destroy$), + ) + .subscribe(); } - - async submit() { - try { - const request = new ProviderUpdateRequest(); - request.name = this.provider.name; - request.businessName = this.provider.businessName; - request.billingEmail = this.provider.billingEmail; - - this.formPromise = this.providerApiService.putProvider(this.providerId, request).then(() => { - return this.syncService.fullSync(true); - }); - await this.formPromise; - this.platformUtilsService.showToast("success", null, this.i18nService.t("providerUpdated")); - } catch (e) { - this.logService.error(`Handled exception: ${e}`); - } + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); } + submit = async () => { + const request = new ProviderUpdateRequest(); + request.name = this.formGroup.value.providerName; + request.businessName = this.formGroup.value.providerName; + request.billingEmail = this.formGroup.value.providerBillingEmail; + + await this.providerApiService.putProvider(this.providerId, request); + await this.syncService.fullSync(true); + this.provider = await this.providerApiService.getProvider(this.providerId); + this.platformUtilsService.showToast("success", null, this.i18nService.t("providerUpdated")); + }; async deleteProvider() { const providerClients = await this.apiService.getProviderClients(this.providerId); @@ -105,7 +118,6 @@ export class AccountComponent { } catch (e) { this.logService.error(e); } - await this.router.navigate(["/"]); } From ab83e822f751ee6f78317d6905a6345f7ba996b2 Mon Sep 17 00:00:00 2001 From: vinith-kovan <156108204+vinith-kovan@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:25:42 +0530 Subject: [PATCH 015/130] [PM-2056] update two factor duo dialog (#8976) * migrating two factor duo component * migrating two factor duo component * two factor duo component migration * two factor duo component migration * removed null check from two-factor-setup * cleanup duo changes * remove ikey and skey references * clean up --------- Co-authored-by: Jake Fink --- .../settings/two-factor-setup.component.ts | 21 ++- .../settings/two-factor-duo.component.html | 156 +++++++----------- .../auth/settings/two-factor-duo.component.ts | 99 ++++++++--- .../settings/two-factor-setup.component.ts | 7 +- 4 files changed, 144 insertions(+), 139 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts index c95ff754c45..b0dd6c63a77 100644 --- a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts @@ -1,6 +1,6 @@ import { Component } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; -import { concatMap, takeUntil, map } from "rxjs"; +import { concatMap, takeUntil, map, lastValueFrom } from "rxjs"; import { tap } from "rxjs/operators"; import { ModalService } from "@bitwarden/angular/services/modal.service"; @@ -16,6 +16,7 @@ import { DialogService } from "@bitwarden/components"; import { TwoFactorDuoComponent } from "../../../auth/settings/two-factor-duo.component"; import { TwoFactorSetupComponent as BaseTwoFactorSetupComponent } from "../../../auth/settings/two-factor-setup.component"; +import { TwoFactorVerifyComponent } from "../../../auth/settings/two-factor-verify.component"; @Component({ selector: "app-two-factor-setup", @@ -65,21 +66,19 @@ export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent { async manage(type: TwoFactorProviderType) { switch (type) { case TwoFactorProviderType.OrganizationDuo: { - const result: AuthResponse = await this.callTwoFactorVerifyDialog( - TwoFactorProviderType.OrganizationDuo, + const twoFactorVerifyDialogRef = TwoFactorVerifyComponent.open(this.dialogService, { + data: { type: type, organizationId: this.organizationId }, + }); + const result: AuthResponse = await lastValueFrom( + twoFactorVerifyDialogRef.closed, ); - if (!result) { return; } + const duoComp = TwoFactorDuoComponent.open(this.dialogService, { data: result }); + const enabled: boolean = await lastValueFrom(duoComp.closed); + this.updateStatus(enabled, TwoFactorProviderType.Duo); - const duoComp = await this.openModal(this.duoModalRef, TwoFactorDuoComponent); - duoComp.type = TwoFactorProviderType.OrganizationDuo; - duoComp.organizationId = this.organizationId; - duoComp.auth(result); - duoComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => { - this.updateStatus(enabled, TwoFactorProviderType.OrganizationDuo); - }); break; } default: diff --git a/apps/web/src/app/auth/settings/two-factor-duo.component.html b/apps/web/src/app/auth/settings/two-factor-duo.component.html index 23ccaf6bde2..6c733ed798a 100644 --- a/apps/web/src/app/auth/settings/two-factor-duo.component.html +++ b/apps/web/src/app/auth/settings/two-factor-duo.component.html @@ -1,98 +1,58 @@ - +
+ + + {{ "twoStepLogin" | i18n }} + Duo + + + + + {{ "twoStepLoginProviderEnabled" | i18n }} + + Duo logo + {{ "twoFactorDuoClientId" | i18n }}: {{ clientId }} +
+ {{ "twoFactorDuoClientSecret" | i18n }}: {{ clientSecret }} +
+ {{ "twoFactorDuoApiHostname" | i18n }}: {{ host }} +
+ + Duo logo +

{{ "twoFactorDuoDesc" | i18n }}

+ + {{ "twoFactorDuoClientId" | i18n }} + + + + {{ "twoFactorDuoClientSecret" | i18n }} + + + + {{ "twoFactorDuoApiHostname" | i18n }} + + +
+
+ + + + +
+
diff --git a/apps/web/src/app/auth/settings/two-factor-duo.component.ts b/apps/web/src/app/auth/settings/two-factor-duo.component.ts index 9a1ec6c4da6..c3ed10ed87b 100644 --- a/apps/web/src/app/auth/settings/two-factor-duo.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-duo.component.ts @@ -1,4 +1,6 @@ -import { Component } from "@angular/core"; +import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; +import { Component, EventEmitter, Inject, Output } from "@angular/core"; +import { FormBuilder, Validators } from "@angular/forms"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; @@ -18,21 +20,26 @@ import { TwoFactorBaseComponent } from "./two-factor-base.component"; templateUrl: "two-factor-duo.component.html", }) export class TwoFactorDuoComponent extends TwoFactorBaseComponent { - type = TwoFactorProviderType.Duo; - clientId: string; - clientSecret: string; - host: string; - formPromise: Promise; + @Output() onChangeStatus: EventEmitter = new EventEmitter(); + type = TwoFactorProviderType.Duo; + formGroup = this.formBuilder.group({ + clientId: ["", [Validators.required]], + clientSecret: ["", [Validators.required]], + host: ["", [Validators.required]], + }); override componentName = "app-two-factor-duo"; constructor( + @Inject(DIALOG_DATA) protected data: AuthResponse, apiService: ApiService, i18nService: I18nService, platformUtilsService: PlatformUtilsService, logService: LogService, userVerificationService: UserVerificationService, dialogService: DialogService, + private formBuilder: FormBuilder, + private dialogRef: DialogRef, ) { super( apiService, @@ -44,43 +51,81 @@ export class TwoFactorDuoComponent extends TwoFactorBaseComponent { ); } - auth(authResponse: AuthResponse) { - super.auth(authResponse); - this.processResponse(authResponse.response); + get clientId() { + return this.formGroup.get("clientId").value; + } + get clientSecret() { + return this.formGroup.get("clientSecret").value; + } + get host() { + return this.formGroup.get("host").value; + } + set clientId(value: string) { + this.formGroup.get("clientId").setValue(value); + } + set clientSecret(value: string) { + this.formGroup.get("clientSecret").setValue(value); + } + set host(value: string) { + this.formGroup.get("host").setValue(value); } - submit() { - if (this.enabled) { - return super.disable(this.formPromise); - } else { - return this.enable(); - } + async ngOnInit() { + super.auth(this.data); + this.processResponse(this.data.response); } + submit = async () => { + this.formGroup.markAllAsTouched(); + if (this.formGroup.invalid) { + return; + } + if (this.enabled) { + await this.disableMethod(); + } else { + await this.enable(); + } + this.onChangeStatus.emit(this.enabled); + }; + protected async enable() { const request = await this.buildRequestModel(UpdateTwoFactorDuoRequest); request.clientId = this.clientId; request.clientSecret = this.clientSecret; request.host = this.host; - return super.enable(async () => { - if (this.organizationId != null) { - this.formPromise = this.apiService.putTwoFactorOrganizationDuo( - this.organizationId, - request, - ); - } else { - this.formPromise = this.apiService.putTwoFactorDuo(request); - } - const response = await this.formPromise; - await this.processResponse(response); - }); + let response: TwoFactorDuoResponse; + + if (this.organizationId != null) { + response = await this.apiService.putTwoFactorOrganizationDuo(this.organizationId, request); + } else { + response = await this.apiService.putTwoFactorDuo(request); + } + + this.processResponse(response); + this.onUpdated.emit(true); } + onClose = () => { + this.dialogRef.close(this.enabled); + }; + private processResponse(response: TwoFactorDuoResponse) { this.clientId = response.clientId; this.clientSecret = response.clientSecret; this.host = response.host; this.enabled = response.enabled; } + + /** + * Strongly typed helper to open a TwoFactorDuoComponentComponent + * @param dialogService Instance of the dialog service that will be used to open the dialog + * @param config Configuration for the dialog + */ + static open = ( + dialogService: DialogService, + config: DialogConfig>, + ) => { + return dialogService.open(TwoFactorDuoComponent, config); + }; } diff --git a/apps/web/src/app/auth/settings/two-factor-setup.component.ts b/apps/web/src/app/auth/settings/two-factor-setup.component.ts index 10f113d4963..d60153230b0 100644 --- a/apps/web/src/app/auth/settings/two-factor-setup.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-setup.component.ts @@ -161,9 +161,10 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy { if (!result) { return; } - const duoComp = await this.openModal(this.duoModalRef, TwoFactorDuoComponent); - duoComp.auth(result); - duoComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => { + const duoComp: DialogRef = TwoFactorDuoComponent.open(this.dialogService, { + data: result, + }); + duoComp.componentInstance.onChangeStatus.subscribe((enabled: boolean) => { this.updateStatus(enabled, TwoFactorProviderType.Duo); }); break; From 89a34a396ce47393296e74e2da247f8d0f071460 Mon Sep 17 00:00:00 2001 From: Tom <144813356+ttalty@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:42:25 -0400 Subject: [PATCH 016/130] Adding the setting of the account to null on logout for web (#9592) Merging. --- apps/web/src/app/app.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index c9fbf359f0f..f9d290de796 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -338,6 +338,7 @@ export class AppComponent implements OnDestroy, OnInit { this.authService.logOut(async () => { await this.stateService.clean({ userId: userId }); await this.accountService.clean(userId); + await this.accountService.switchAccount(null); await logoutPromise; From a3514001c0c5849eb8a41b562eda18199886faa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Wed, 26 Jun 2024 15:41:02 -0400 Subject: [PATCH 017/130] shuffle copied array (#9847) --- libs/common/src/tools/generator/random.ts | 4 ++-- .../generator/core/src/engine/crypto-service-randomizer.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/common/src/tools/generator/random.ts b/libs/common/src/tools/generator/random.ts index 6b72e3cd916..1400ed11758 100644 --- a/libs/common/src/tools/generator/random.ts +++ b/libs/common/src/tools/generator/random.ts @@ -31,9 +31,9 @@ export class CryptoServiceRandomizer implements Randomizer { async shuffle(items: Array, options?: { copy?: boolean }) { const shuffled = options?.copy ?? true ? [...items] : items; - for (let i = items.length - 1; i > 0; i--) { + for (let i = shuffled.length - 1; i > 0; i--) { const j = await this.uniform(0, i); - [items[i], items[j]] = [items[j], items[i]]; + [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; } return shuffled; diff --git a/libs/tools/generator/core/src/engine/crypto-service-randomizer.ts b/libs/tools/generator/core/src/engine/crypto-service-randomizer.ts index a15440836d4..5320fad681c 100644 --- a/libs/tools/generator/core/src/engine/crypto-service-randomizer.ts +++ b/libs/tools/generator/core/src/engine/crypto-service-randomizer.ts @@ -31,9 +31,9 @@ export class CryptoServiceRandomizer implements Randomizer { async shuffle(items: Array, options?: { copy?: boolean }) { const shuffled = options?.copy ?? true ? [...items] : items; - for (let i = items.length - 1; i > 0; i--) { + for (let i = shuffled.length - 1; i > 0; i--) { const j = await this.uniform(0, i); - [items[i], items[j]] = [items[j], items[i]]; + [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; } return shuffled; From 76a3cb5a466b6937afcdc3d3476cfd59ced6baf4 Mon Sep 17 00:00:00 2001 From: Addison Beck Date: Wed, 26 Jun 2024 16:01:05 -0400 Subject: [PATCH 018/130] Update CLI storefronts to use bitwarden licensed artifacts (#9827) * Update the build job to use `bit` artifacts for stores * Update the CLI's license in `package.json` for the NPM store * Add license configuration to `snapcraft.yaml` --- .github/workflows/build-cli.yml | 10 +++++----- apps/cli/package.json | 2 +- apps/cli/stores/snap/snapcraft.yaml | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index 5e333b3b58a..1c2693f2dec 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -240,7 +240,7 @@ jobs: - name: Package Chocolatey shell: pwsh - if: ${{ matrix.license_type.prefix }} == 'oss' + if: ${{ matrix.license_type.prefix }} == 'bit' run: | Copy-Item -Path stores/chocolatey -Destination dist/chocolatey -Recurse Copy-Item dist/${{ matrix.license_type.prefix }}/windows/bw.exe -Destination dist/chocolatey/tools @@ -282,7 +282,7 @@ jobs: if-no-files-found: error - name: Upload Chocolatey asset - if: matrix.license_type.prefix == 'oss' + if: matrix.license_type.prefix == 'bit' uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg @@ -290,7 +290,7 @@ jobs: if-no-files-found: error - name: Upload NPM Build Directory asset - if: matrix.license_type.prefix == 'oss' + if: matrix.license_type.prefix == 'bit' uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip @@ -320,13 +320,13 @@ jobs: - name: Get bw linux cli uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: - name: bw-oss-linux-${{ env._PACKAGE_VERSION }}.zip + name: bw-bit-linux-${{ env._PACKAGE_VERSION }}.zip path: apps/cli/dist/snap - name: Rename snap artifact run: | cd dist/snap - mv bw-oss-linux-${{ env._PACKAGE_VERSION }}.zip bw-linux-${{ env._PACKAGE_VERSION }}.zip + mv bw-bit-linux-${{ env._PACKAGE_VERSION }}.zip bw-linux-${{ env._PACKAGE_VERSION }}.zip - name: Setup Snap Package run: | diff --git a/apps/cli/package.json b/apps/cli/package.json index 97b4dcf2ecf..2fb60b76240 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/bitwarden/clients" }, - "license": "GPL-3.0-only", + "license": "SEE LICENSE IN LICENSE.txt", "scripts": { "clean": "rimraf dist", "build:oss": "webpack", diff --git a/apps/cli/stores/snap/snapcraft.yaml b/apps/cli/stores/snap/snapcraft.yaml index 865adcfe4b8..c79d8fc399c 100644 --- a/apps/cli/stores/snap/snapcraft.yaml +++ b/apps/cli/stores/snap/snapcraft.yaml @@ -1,6 +1,7 @@ name: bw version: __version__ summary: Bitwarden CLI - A secure and free password manager for all of your devices. +license: Proprietary description: | Bitwarden, Inc. is the parent company of 8bit Solutions LLC. From 794da48437d9e8c5ec84ec069437eb6d54a9002b Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Thu, 27 Jun 2024 06:43:02 +1000 Subject: [PATCH 019/130] [AC-2806] Add support for conditional routing based on feature flag value (#9798) Co-authored-by: Shane Melton --- .../platform/utils/feature-flagged-route.ts | 53 +++++++++++++++++++ .../angular/src/utils/component-route-swap.ts | 11 ++-- 2 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 libs/angular/src/platform/utils/feature-flagged-route.ts diff --git a/libs/angular/src/platform/utils/feature-flagged-route.ts b/libs/angular/src/platform/utils/feature-flagged-route.ts new file mode 100644 index 00000000000..a08e4d86cf3 --- /dev/null +++ b/libs/angular/src/platform/utils/feature-flagged-route.ts @@ -0,0 +1,53 @@ +import { Type, inject } from "@angular/core"; +import { Route, Routes } from "@angular/router"; +import { map } from "rxjs"; + +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; + +import { componentRouteSwap } from "../../utils/component-route-swap"; + +/** + * @param defaultComponent The component to be used when the feature flag is off. + * @param flaggedComponent The component to be used when the feature flag is on. + * @param featureFlag The feature flag to evaluate + * @param routeOptions The shared route options to apply to both components. + */ +type FeatureFlaggedRouteConfig = { + defaultComponent: Type; + flaggedComponent: Type; + featureFlag: FeatureFlag; + routeOptions: Omit; +}; + +/** + * Swap between two routes at runtime based on the value of a feature flag. + * The routes share a common path and configuration but load different components. + * @param config See {@link FeatureFlaggedRouteConfig} + * @returns A tuple containing the conditional configuration for the two routes. This should be unpacked into your existing Routes array. + * @example + * const routes: Routes = [ + * ...featureFlaggedRoute({ + * defaultComponent: GroupsComponent, + * flaggedComponent: GroupsNewComponent, + * featureFlag: FeatureFlag.GroupsComponentRefactor, + * routeOptions: { + * path: "groups", + * canActivate: [OrganizationPermissionsGuard], + * }, + * }), + * ] + */ +export function featureFlaggedRoute(config: FeatureFlaggedRouteConfig): Routes { + const canMatch$ = () => + inject(ConfigService) + .getFeatureFlag$(config.featureFlag) + .pipe(map((flagValue) => flagValue === true)); + + return componentRouteSwap( + config.defaultComponent, + config.flaggedComponent, + canMatch$, + config.routeOptions, + ); +} diff --git a/libs/angular/src/utils/component-route-swap.ts b/libs/angular/src/utils/component-route-swap.ts index 1a45671d2be..ab44f49b659 100644 --- a/libs/angular/src/utils/component-route-swap.ts +++ b/libs/angular/src/utils/component-route-swap.ts @@ -1,5 +1,5 @@ import { Type } from "@angular/core"; -import { Route, Routes } from "@angular/router"; +import { CanMatchFn, Route, Routes } from "@angular/router"; /** * Helper function to swap between two components based on an async condition. The async condition is evaluated @@ -32,7 +32,7 @@ import { Route, Routes } from "@angular/router"; export function componentRouteSwap( defaultComponent: Type, altComponent: Type, - shouldSwapFn: () => Promise, + shouldSwapFn: CanMatchFn, options: Route, altOptions?: Route, ): Routes { @@ -46,12 +46,7 @@ export function componentRouteSwap( const altRoute: Route = { ...selectedAltOptions, component: altComponent, - canMatch: [ - async () => { - return await shouldSwapFn(); - }, - ...(selectedAltOptions.canMatch ?? []), - ], + canMatch: [shouldSwapFn, ...(selectedAltOptions.canMatch ?? [])], }; // Return the alternate route first, so it is evaluated first. From 039c5ee6acfb4154961b4b973a9c5491fe04b20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ch=C4=99ci=C5=84ski?= Date: Thu, 27 Jun 2024 13:50:54 +0200 Subject: [PATCH 020/130] [BRE-151] Fix Staged Rollout Desktop workflow (#9824) --- .github/workflows/staged-rollout-desktop.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/staged-rollout-desktop.yml b/.github/workflows/staged-rollout-desktop.yml index a6ca2f1e319..1f751507640 100644 --- a/.github/workflows/staged-rollout-desktop.yml +++ b/.github/workflows/staged-rollout-desktop.yml @@ -41,11 +41,11 @@ jobs: AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }} run: | aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest.yml . \ - --quiet \ + --quiet aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest-linux.yml . \ - --quiet \ + --quiet aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest-mac.yml . \ - --quiet \ + --quiet - name: Check new rollout percentage env: From 0fc489cfa0e64aa11d09d66dbe30f07500108b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ch=C4=99ci=C5=84ski?= Date: Thu, 27 Jun 2024 13:51:29 +0200 Subject: [PATCH 021/130] [BRE-133] Fix Partial Desktop Release (#9825) --- .github/workflows/release-desktop.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index dc6957d00d6..eb63a53f2ea 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -29,11 +29,6 @@ on: required: true default: true type: boolean - electron_publish: - description: 'Publish Electron to S3 bucket' - required: true - default: true - type: boolean github_release: description: 'Publish GitHub release' required: true @@ -142,7 +137,6 @@ jobs: run: mv Bitwarden-${{ env.PKG_VERSION }}-universal.pkg Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive - name: Set staged rollout percentage - if: ${{ github.event.inputs.electron_publish == 'true' }} env: RELEASE_CHANNEL: ${{ steps.release-channel.outputs.channel }} ROLLOUT_PCT: ${{ inputs.rollout_percentage }} @@ -152,7 +146,7 @@ jobs: echo "stagingPercentage: ${ROLLOUT_PCT}" >> apps/desktop/artifacts/${RELEASE_CHANNEL}-mac.yml - name: Publish artifacts to S3 - if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish == 'true' }} + if: ${{ github.event.inputs.release_type != 'Dry Run' }} env: AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }} AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }} From 98c6cc4a7ef42d4fd35ba4c4517f9627c0060400 Mon Sep 17 00:00:00 2001 From: Tom <144813356+ttalty@users.noreply.github.com> Date: Thu, 27 Jun 2024 08:44:43 -0400 Subject: [PATCH 022/130] [PM-5957] CLI - List items long runtime (#9589) * Initial checking of collect many * should update to better handle parameters * cleaning up event collection params * Adding documentation * Removing commented out code saved for testing * Adding pr changes and using the account service for event collection user id * browser main.background event collection service needed the account service --- .../browser/src/background/main.background.ts | 1 + apps/cli/src/commands/list.command.ts | 12 +-- apps/cli/src/service-container.ts | 1 + .../src/services/jslib-services.module.ts | 1 + .../event/event-collection.service.ts | 6 ++ .../event/event-collection.service.ts | 85 +++++++++++++++---- 6 files changed, 80 insertions(+), 26 deletions(-) diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 8e11e7e193e..0ea0be9ffdb 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -869,6 +869,7 @@ export default class MainBackground { this.organizationService, this.eventUploadService, this.authService, + this.accountService, ); this.totpService = new TotpService(this.cryptoFunctionService, this.logService); diff --git a/apps/cli/src/commands/list.command.ts b/apps/cli/src/commands/list.command.ts index 536c9e3b8c2..88574635e1c 100644 --- a/apps/cli/src/commands/list.command.ts +++ b/apps/cli/src/commands/list.command.ts @@ -128,17 +128,7 @@ export class ListCommand { ciphers = this.searchService.searchCiphersBasic(ciphers, options.search, options.trash); } - for (let i = 0; i < ciphers.length; i++) { - const c = ciphers[i]; - // Set upload immediately on the last item in the ciphers collection to avoid the event collection - // service from uploading each time. - await this.eventCollectionService.collect( - EventType.Cipher_ClientViewed, - c.id, - i === ciphers.length - 1, - c.organizationId, - ); - } + await this.eventCollectionService.collectMany(EventType.Cipher_ClientViewed, ciphers, true); const res = new ListResponse(ciphers.map((o) => new CipherResponse(o))); return Response.success(res); diff --git a/apps/cli/src/service-container.ts b/apps/cli/src/service-container.ts index 2d5f83787f1..fe9de868226 100644 --- a/apps/cli/src/service-container.ts +++ b/apps/cli/src/service-container.ts @@ -729,6 +729,7 @@ export class ServiceContainer { this.organizationService, this.eventUploadService, this.authService, + this.accountService, ); this.providerApiService = new ProviderApiService(this.apiService); diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index e06b2788761..388a149bfa1 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -830,6 +830,7 @@ const safeProviders: SafeProvider[] = [ OrganizationServiceAbstraction, EventUploadServiceAbstraction, AuthServiceAbstraction, + AccountServiceAbstraction, ], }), safeProvider({ diff --git a/libs/common/src/abstractions/event/event-collection.service.ts b/libs/common/src/abstractions/event/event-collection.service.ts index 15930dbc2e2..38f226cc2d6 100644 --- a/libs/common/src/abstractions/event/event-collection.service.ts +++ b/libs/common/src/abstractions/event/event-collection.service.ts @@ -1,6 +1,12 @@ import { EventType } from "../../enums"; +import { CipherView } from "../../vault/models/view/cipher.view"; export abstract class EventCollectionService { + collectMany: ( + eventType: EventType, + ciphers: CipherView[], + uploadImmediately?: boolean, + ) => Promise; collect: ( eventType: EventType, cipherId?: string, diff --git a/libs/common/src/services/event/event-collection.service.ts b/libs/common/src/services/event/event-collection.service.ts index 1482bb8b61e..570d84c6598 100644 --- a/libs/common/src/services/event/event-collection.service.ts +++ b/libs/common/src/services/event/event-collection.service.ts @@ -1,25 +1,76 @@ -import { firstValueFrom, map, from, zip } from "rxjs"; +import { firstValueFrom, map, from, zip, Observable } from "rxjs"; import { EventCollectionService as EventCollectionServiceAbstraction } from "../../abstractions/event/event-collection.service"; import { EventUploadService } from "../../abstractions/event/event-upload.service"; import { OrganizationService } from "../../admin-console/abstractions/organization/organization.service.abstraction"; +import { AccountService } from "../../auth/abstractions/account.service"; import { AuthService } from "../../auth/abstractions/auth.service"; import { AuthenticationStatus } from "../../auth/enums/authentication-status"; import { EventType } from "../../enums"; import { EventData } from "../../models/data/event.data"; import { StateProvider } from "../../platform/state"; import { CipherService } from "../../vault/abstractions/cipher.service"; +import { CipherView } from "../../vault/models/view/cipher.view"; import { EVENT_COLLECTION } from "./key-definitions"; export class EventCollectionService implements EventCollectionServiceAbstraction { + private orgIds$: Observable; + constructor( private cipherService: CipherService, private stateProvider: StateProvider, private organizationService: OrganizationService, private eventUploadService: EventUploadService, private authService: AuthService, - ) {} + private accountService: AccountService, + ) { + this.orgIds$ = this.organizationService.organizations$.pipe( + map((orgs) => orgs?.filter((o) => o.useEvents)?.map((x) => x.id) ?? []), + ); + } + + /** Adds an event to the active user's event collection + * @param eventType the event type to be added + * @param ciphers The collection of ciphers to log events for + * @param uploadImmediately in some cases the recorded events should be uploaded right after being added + */ + async collectMany( + eventType: EventType, + ciphers: CipherView[], + uploadImmediately = false, + ): Promise { + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))); + const eventStore = this.stateProvider.getUser(userId, EVENT_COLLECTION); + + if (!(await this.shouldUpdate(null, eventType, ciphers))) { + return; + } + + const events$ = this.orgIds$.pipe( + map((orgs) => + ciphers + .filter((c) => orgs.includes(c.organizationId)) + .map((c) => ({ + type: eventType, + cipherId: c.id, + date: new Date().toISOString(), + organizationId: c.organizationId, + })), + ), + ); + + await eventStore.update( + (currentEvents, newEvents) => [...(currentEvents ?? []), ...newEvents], + { + combineLatestWith: events$, + }, + ); + + if (uploadImmediately) { + await this.eventUploadService.uploadEvents(); + } + } /** Adds an event to the active user's event collection * @param eventType the event type to be added @@ -33,10 +84,10 @@ export class EventCollectionService implements EventCollectionServiceAbstraction uploadImmediately = false, organizationId: string = null, ): Promise { - const userId = await firstValueFrom(this.stateProvider.activeUserId$); + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))); const eventStore = this.stateProvider.getUser(userId, EVENT_COLLECTION); - if (!(await this.shouldUpdate(cipherId, organizationId, eventType))) { + if (!(await this.shouldUpdate(organizationId, eventType, undefined, cipherId))) { return; } @@ -62,18 +113,15 @@ export class EventCollectionService implements EventCollectionServiceAbstraction * @param organizationId the organization for the event */ private async shouldUpdate( - cipherId: string = null, organizationId: string = null, eventType: EventType = null, + ciphers: CipherView[] = [], + cipherId?: string, ): Promise { - const orgIds$ = this.organizationService.organizations$.pipe( - map((orgs) => orgs?.filter((o) => o.useEvents)?.map((x) => x.id) ?? []), - ); - const cipher$ = from(this.cipherService.get(cipherId)); const [authStatus, orgIds, cipher] = await firstValueFrom( - zip(this.authService.activeAccountStatus$, orgIds$, cipher$), + zip(this.authService.activeAccountStatus$, this.orgIds$, cipher$), ); // The user must be authorized @@ -91,14 +139,21 @@ export class EventCollectionService implements EventCollectionServiceAbstraction return true; } - // If the cipher is null there must be an organization id provided - if (cipher == null && organizationId == null) { + // If the cipherId was provided and a cipher exists, add it to the collection + if (cipher != null) { + ciphers.push(new CipherView(cipher)); + } + + // If no ciphers there must be an organization id provided + if ((ciphers == null || ciphers.length == 0) && organizationId == null) { return false; } - // If the cipher is present it must be in the user's org list - if (cipher != null && !orgIds.includes(cipher?.organizationId)) { - return false; + // If the input list of ciphers is provided. Check the ciphers to see if any + // are in the user's org list + if (ciphers != null && ciphers.length > 0) { + const filtered = ciphers.filter((c) => orgIds.includes(c.organizationId)); + return filtered.length > 0; } // If the organization id is provided it must be in the user's org list From 5ce4e8f4e53a7e53e71b17e89e8c2a6b698891ef Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:50:45 -0500 Subject: [PATCH 023/130] [PM-7897] Attachments - Part 1 (#9715) * add v2 attachments page * add add attachment fields * add file upload UI * move cipher-attachments to a new component * load cipher and add initial submit * add list of existing attachments * fix incorrect toast usage * integrate with bit submit states * add new max file translation without the period * refactor attachments v2 component * remove default list styles * add tests for attachments components * use `CipherId` type * pass submit button reference to the underlying form * remove bitFormButton * [PM-7897] Attachments Part 2 (#9755) * make `isNew` param optional * emit success output after upload * navigate the user to the edit screen after an upload * allow for the deletion of an attachment * add download attachment component to attachments view * implement base attachment link * add premium redirect * show specific error message for free organizations * make open-attachments a button so it is keyboard accessible * fix lint error * use bitItem * using bitAction rather than standalone loading/deleting value * remove extra title, unneeded because of the appA11yTitle usage * use `replaceUrl` to avoid the back button going to the attachments page * use bit-item for consistency * show error when a user tries to open an attachment that is a part of a free org * add `CipherId` type for failed builds --- apps/browser/src/_locales/en/messages.json | 36 +++ apps/browser/src/popup/app-routing.module.ts | 6 +- .../add-edit/add-edit-v2.component.html | 2 + .../add-edit/add-edit-v2.component.ts | 9 +- .../attachments/attachments-v2.component.html | 24 ++ .../attachments-v2.component.spec.ts | 122 +++++++++ .../attachments/attachments-v2.component.ts | 62 +++++ .../cipher-attachments.component.html | 66 +++++ .../cipher-attachments.component.spec.ts | 255 ++++++++++++++++++ .../cipher-attachments.component.ts | 211 +++++++++++++++ .../delete-attachment.component.html | 9 + .../delete-attachment.component.spec.ts | 105 ++++++++ .../delete-attachment.component.ts | 66 +++++ .../download-attachment.component.html | 8 + .../download-attachment.component.spec.ts | 144 ++++++++++ .../download-attachment.component.ts | 104 +++++++ .../open-attachments.component.html | 14 + .../open-attachments.component.spec.ts | 166 ++++++++++++ .../open-attachments.component.ts | 101 +++++++ 19 files changed, 1506 insertions(+), 4 deletions(-) create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.html create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.html create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.spec.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.html create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.spec.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.html create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.spec.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 64f039bb8b2..2675e38ee8c 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -3498,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment":{ + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 51152ba0f71..69e6d36afa9 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -68,6 +68,7 @@ import { VaultItemsComponent } from "../vault/popup/components/vault/vault-items import { VaultV2Component } from "../vault/popup/components/vault/vault-v2.component"; import { ViewComponent } from "../vault/popup/components/vault/view.component"; import { AddEditV2Component } from "../vault/popup/components/vault-v2/add-edit/add-edit-v2.component"; +import { AttachmentsV2Component } from "../vault/popup/components/vault-v2/attachments/attachments-v2.component"; import { AppearanceComponent } from "../vault/popup/settings/appearance.component"; import { FolderAddEditComponent } from "../vault/popup/settings/folder-add-edit.component"; import { FoldersComponent } from "../vault/popup/settings/folders.component"; @@ -230,12 +231,11 @@ const routes: Routes = [ canActivate: [AuthGuard], data: { state: "collections" }, }, - { + ...extensionRefreshSwap(AttachmentsComponent, AttachmentsV2Component, { path: "attachments", - component: AttachmentsComponent, canActivate: [AuthGuard], data: { state: "attachments" }, - }, + }), { path: "generator", component: GeneratorComponent, 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 09b764cbc8f..c6fd12b2493 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 @@ -1,6 +1,8 @@ + + + + diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts new file mode 100644 index 00000000000..0f09d12db9f --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.spec.ts @@ -0,0 +1,122 @@ +import { Component, Input } from "@angular/core"; +import { ComponentFixture, TestBed, fakeAsync, tick } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { ActivatedRoute, Router } from "@angular/router"; +import { mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; + +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.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 { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherType } from "@bitwarden/common/vault/enums"; +import { ButtonComponent } from "@bitwarden/components"; + +import { PopupFooterComponent } from "../../../../../platform/popup/layout/popup-footer.component"; +import { PopupHeaderComponent } from "../../../../../platform/popup/layout/popup-header.component"; + +import { AttachmentsV2Component } from "./attachments-v2.component"; +import { CipherAttachmentsComponent } from "./cipher-attachments/cipher-attachments.component"; + +@Component({ + standalone: true, + selector: "popup-header", + template: ``, +}) +class MockPopupHeaderComponent { + @Input() pageTitle: string; +} + +@Component({ + standalone: true, + selector: "popup-footer", + template: ``, +}) +class MockPopupFooterComponent { + @Input() pageTitle: string; +} + +describe("AttachmentsV2Component", () => { + let component: AttachmentsV2Component; + let fixture: ComponentFixture; + const queryParams = new BehaviorSubject<{ cipherId: string }>({ cipherId: "5555-444-3333" }); + let cipherAttachment: CipherAttachmentsComponent; + const navigate = jest.fn(); + + const cipherDomain = { + type: CipherType.Login, + name: "Test Login", + }; + + const cipherServiceGet = jest.fn().mockResolvedValue(cipherDomain); + + beforeEach(async () => { + cipherServiceGet.mockClear(); + navigate.mockClear(); + + await TestBed.configureTestingModule({ + imports: [AttachmentsV2Component], + providers: [ + { provide: LogService, useValue: mock() }, + { provide: ConfigService, useValue: mock() }, + { provide: PlatformUtilsService, useValue: mock() }, + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: Router, useValue: { navigate } }, + { + provide: ActivatedRoute, + useValue: { + queryParams, + }, + }, + { + provide: CipherService, + useValue: { + get: cipherServiceGet, + }, + }, + ], + }) + .overrideComponent(AttachmentsV2Component, { + remove: { + imports: [PopupHeaderComponent, PopupFooterComponent], + }, + add: { + imports: [MockPopupHeaderComponent, MockPopupFooterComponent], + }, + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AttachmentsV2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + + cipherAttachment = fixture.debugElement.query( + By.directive(CipherAttachmentsComponent), + ).componentInstance; + }); + + it("sets `cipherId` from query params", () => { + expect(component.cipherId).toBe("5555-444-3333"); + }); + + it("passes the submit button to the cipher attachments component", () => { + const submitBtn = fixture.debugElement.queryAll(By.directive(ButtonComponent))[1] + .componentInstance; + + expect(cipherAttachment.submitBtn).toEqual(submitBtn); + }); + + it("navigates the user to the edit view `onUploadSuccess`", fakeAsync(() => { + cipherAttachment.onUploadSuccess.emit(); + + tick(); + + expect(navigate).toHaveBeenCalledWith(["/edit-cipher"], { + queryParams: { cipherId: "5555-444-3333", type: CipherType.Login }, + replaceUrl: true, + }); + })); +}); diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts new file mode 100644 index 00000000000..da0def529c2 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/attachments-v2.component.ts @@ -0,0 +1,62 @@ +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { ActivatedRoute, Router } from "@angular/router"; +import { first } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { CipherId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { ButtonModule } from "@bitwarden/components"; + +import { PopOutComponent } from "../../../../../platform/popup/components/pop-out.component"; +import { PopupFooterComponent } from "../../../../../platform/popup/layout/popup-footer.component"; +import { PopupHeaderComponent } from "../../../../../platform/popup/layout/popup-header.component"; +import { PopupPageComponent } from "../../../../../platform/popup/layout/popup-page.component"; + +import { CipherAttachmentsComponent } from "./cipher-attachments/cipher-attachments.component"; + +@Component({ + standalone: true, + selector: "app-attachments-v2", + templateUrl: "./attachments-v2.component.html", + imports: [ + CommonModule, + ButtonModule, + JslibModule, + CipherAttachmentsComponent, + PopupPageComponent, + PopupHeaderComponent, + PopupFooterComponent, + PopOutComponent, + ], +}) +export class AttachmentsV2Component { + /** The `id` tied to the underlying HTMLFormElement */ + attachmentFormId = CipherAttachmentsComponent.attachmentFormID; + + /** Id of the cipher */ + cipherId: CipherId; + + constructor( + private router: Router, + private cipherService: CipherService, + route: ActivatedRoute, + ) { + route.queryParams.pipe(takeUntilDestroyed(), first()).subscribe(({ cipherId }) => { + this.cipherId = cipherId; + }); + } + + /** Navigate the user back to the edit screen after uploading an attachment */ + async navigateToEditScreen() { + const cipherDomain = await this.cipherService.get(this.cipherId); + + void this.router.navigate(["/edit-cipher"], { + queryParams: { cipherId: this.cipherId, type: cipherDomain.type }, + // "replaceUrl" so the /attachments route is not in the history, thus when a back button + // is clicked, the user is taken to the view screen instead of the attachments screen + replaceUrl: true, + }); + } +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.html b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.html new file mode 100644 index 00000000000..bcadf7a4336 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.html @@ -0,0 +1,66 @@ +

{{ "attachments" | i18n }}

+ +
    +
  • + + + {{ attachment.fileName }} + {{ attachment.sizeName }} + + + + + + + + + + +
  • +
+ +
+ + +
+ + + + + +
+

+ {{ "maxFileSizeSansPunctuation" | i18n }} +

+
+
diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.spec.ts new file mode 100644 index 00000000000..8b5a76b3f32 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.spec.ts @@ -0,0 +1,255 @@ +import { Component, Input } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { mock } from "jest-mock-extended"; + +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.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 { CipherId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherType } from "@bitwarden/common/vault/enums"; +import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { ButtonComponent, ToastService } from "@bitwarden/components"; + +import { CipherAttachmentsComponent } from "./cipher-attachments.component"; +import { DeleteAttachmentComponent } from "./delete-attachment/delete-attachment.component"; +import { DownloadAttachmentComponent } from "./download-attachment/download-attachment.component"; + +@Component({ + standalone: true, + selector: "app-download-attachment", + template: "", +}) +class MockDownloadAttachmentComponent { + @Input() attachment: AttachmentView; + @Input() cipher: CipherView; +} + +describe("CipherAttachmentsComponent", () => { + let component: CipherAttachmentsComponent; + let fixture: ComponentFixture; + const showToast = jest.fn(); + const cipherView = { + id: "5555-444-3333", + type: CipherType.Login, + name: "Test Login", + login: { + username: "username", + password: "password", + }, + } as CipherView; + + const cipherDomain = { + decrypt: () => cipherView, + }; + + const cipherServiceGet = jest.fn().mockResolvedValue(cipherDomain); + const saveAttachmentWithServer = jest.fn().mockResolvedValue(cipherDomain); + + beforeEach(async () => { + cipherServiceGet.mockClear(); + showToast.mockClear(); + saveAttachmentWithServer.mockClear().mockResolvedValue(cipherDomain); + + await TestBed.configureTestingModule({ + imports: [CipherAttachmentsComponent], + providers: [ + { + provide: CipherService, + useValue: { + get: cipherServiceGet, + saveAttachmentWithServer, + getKeyForCipherKeyDecryption: () => Promise.resolve(null), + }, + }, + { + provide: ToastService, + useValue: { + showToast, + }, + }, + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: LogService, useValue: mock() }, + { provide: ConfigService, useValue: mock() }, + { provide: PlatformUtilsService, useValue: mock() }, + ], + }) + .overrideComponent(CipherAttachmentsComponent, { + remove: { + imports: [DownloadAttachmentComponent], + }, + add: { + imports: [MockDownloadAttachmentComponent], + }, + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(CipherAttachmentsComponent); + component = fixture.componentInstance; + component.cipherId = "5555-444-3333" as CipherId; + component.submitBtn = {} as ButtonComponent; + fixture.detectChanges(); + }); + + it("fetches cipherView using `cipherId`", async () => { + await component.ngOnInit(); + + expect(cipherServiceGet).toHaveBeenCalledWith("5555-444-3333"); + expect(component.cipher).toEqual(cipherView); + }); + + describe("bitSubmit", () => { + beforeEach(() => { + component.submitBtn.disabled = undefined; + component.submitBtn.loading = undefined; + }); + + it("updates sets initial state of the submit button", async () => { + await component.ngOnInit(); + + expect(component.submitBtn.disabled).toBe(true); + }); + + it("sets submitBtn loading state", () => { + component.bitSubmit.loading = true; + + expect(component.submitBtn.loading).toBe(true); + + component.bitSubmit.loading = false; + + expect(component.submitBtn.loading).toBe(false); + }); + + it("sets submitBtn disabled state", () => { + component.bitSubmit.disabled = true; + + expect(component.submitBtn.disabled).toBe(true); + + component.bitSubmit.disabled = false; + + expect(component.submitBtn.disabled).toBe(false); + }); + }); + + describe("attachmentForm", () => { + let file: File; + + beforeEach(() => { + component.submitBtn.disabled = undefined; + file = new File([""], "attachment.txt", { type: "text/plain" }); + + const inputElement = fixture.debugElement.query(By.css("input[type=file]")); + + // Set the file value of the input element + Object.defineProperty(inputElement.nativeElement, "files", { + value: [file], + writable: false, + }); + + // Trigger change event, for event listeners + inputElement.nativeElement.dispatchEvent(new InputEvent("change")); + }); + + it("sets value of `file` control when input changes", () => { + expect(component.attachmentForm.controls.file.value.name).toEqual(file.name); + }); + + it("updates disabled state of submit button", () => { + expect(component.submitBtn.disabled).toBe(false); + }); + }); + + describe("submit", () => { + describe("error", () => { + it("shows error toast if no file is selected", async () => { + await component.submit(); + + expect(showToast).toHaveBeenCalledWith({ + variant: "error", + title: "errorOccurred", + message: "selectFile", + }); + }); + + it("shows error toast if file size is greater than 500MB", async () => { + component.attachmentForm.controls.file.setValue({ + size: 524288001, + } as File); + + await component.submit(); + + expect(showToast).toHaveBeenCalledWith({ + variant: "error", + title: "errorOccurred", + message: "maxFileSize", + }); + }); + }); + + describe("success", () => { + const file = { size: 524287999 } as File; + + beforeEach(() => { + component.attachmentForm.controls.file.setValue(file); + }); + + it("calls `saveAttachmentWithServer`", async () => { + await component.submit(); + + expect(saveAttachmentWithServer).toHaveBeenCalledWith(cipherDomain, file); + }); + + it("resets form and input values", async () => { + await component.submit(); + + const fileInput = fixture.debugElement.query(By.css("input[type=file]")); + + expect(fileInput.nativeElement.value).toEqual(""); + expect(component.attachmentForm.controls.file.value).toEqual(null); + }); + + it("shows success toast", async () => { + await component.submit(); + + expect(showToast).toHaveBeenCalledWith({ + variant: "success", + title: null, + message: "attachmentSaved", + }); + }); + + it('emits "onUploadSuccess"', async () => { + const emitSpy = jest.spyOn(component.onUploadSuccess, "emit"); + + await component.submit(); + + expect(emitSpy).toHaveBeenCalled(); + }); + }); + }); + + describe("removeAttachment", () => { + const attachment = { id: "1234-5678" } as AttachmentView; + + beforeEach(() => { + component.cipher.attachments = [attachment]; + + fixture.detectChanges(); + }); + + it("removes attachment from cipher", () => { + const deleteAttachmentComponent = fixture.debugElement.query( + By.directive(DeleteAttachmentComponent), + ).componentInstance as DeleteAttachmentComponent; + + deleteAttachmentComponent.onDeletionSuccess.emit(); + + expect(component.cipher.attachments).toEqual([]); + }); + }); +}); diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.ts new file mode 100644 index 00000000000..21115955653 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/cipher-attachments.component.ts @@ -0,0 +1,211 @@ +import { CommonModule } from "@angular/common"; +import { + AfterViewInit, + Component, + DestroyRef, + ElementRef, + EventEmitter, + Input, + OnInit, + Output, + ViewChild, + inject, +} from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { + FormBuilder, + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from "@angular/forms"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { CipherId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; +import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { + AsyncActionsModule, + BitSubmitDirective, + ButtonComponent, + ButtonModule, + CardComponent, + ItemModule, + ToastService, + TypographyModule, +} from "@bitwarden/components"; + +import { DeleteAttachmentComponent } from "./delete-attachment/delete-attachment.component"; +import { DownloadAttachmentComponent } from "./download-attachment/download-attachment.component"; + +type CipherAttachmentForm = FormGroup<{ + file: FormControl; +}>; + +@Component({ + standalone: true, + selector: "app-cipher-attachments", + templateUrl: "./cipher-attachments.component.html", + imports: [ + AsyncActionsModule, + ButtonModule, + CommonModule, + ItemModule, + JslibModule, + ReactiveFormsModule, + TypographyModule, + CardComponent, + DeleteAttachmentComponent, + DownloadAttachmentComponent, + ], +}) +export class CipherAttachmentsComponent implements OnInit, AfterViewInit { + /** `id` associated with the form element */ + static attachmentFormID = "attachmentForm"; + + /** Reference to the file HTMLInputElement */ + @ViewChild("fileInput", { read: ElementRef }) private fileInput: ElementRef; + + /** Reference to the BitSubmitDirective */ + @ViewChild(BitSubmitDirective) bitSubmit: BitSubmitDirective; + + /** The `id` of the cipher in context */ + @Input({ required: true }) cipherId: CipherId; + + /** An optional submit button, whose loading/disabled state will be tied to the form state. */ + @Input() submitBtn?: ButtonComponent; + + /** Emits after a file has been successfully uploaded */ + @Output() onUploadSuccess = new EventEmitter(); + + cipher: CipherView; + + attachmentForm: CipherAttachmentForm = this.formBuilder.group({ + file: new FormControl(null, [Validators.required]), + }); + + private cipherDomain: Cipher; + private destroy$ = inject(DestroyRef); + + constructor( + private cipherService: CipherService, + private i18nService: I18nService, + private formBuilder: FormBuilder, + private logService: LogService, + private toastService: ToastService, + ) { + this.attachmentForm.statusChanges.pipe(takeUntilDestroyed()).subscribe((status) => { + if (!this.submitBtn) { + return; + } + + this.submitBtn.disabled = status !== "VALID"; + }); + } + + async ngOnInit(): Promise { + this.cipherDomain = await this.cipherService.get(this.cipherId); + this.cipher = await this.cipherDomain.decrypt( + await this.cipherService.getKeyForCipherKeyDecryption(this.cipherDomain), + ); + + // Update the initial state of the submit button + if (this.submitBtn) { + this.submitBtn.disabled = !this.attachmentForm.valid; + } + } + + ngAfterViewInit(): void { + this.bitSubmit.loading$.pipe(takeUntilDestroyed(this.destroy$)).subscribe((loading) => { + if (!this.submitBtn) { + return; + } + + this.submitBtn.loading = loading; + }); + + this.bitSubmit.disabled$.pipe(takeUntilDestroyed(this.destroy$)).subscribe((disabled) => { + if (!this.submitBtn) { + return; + } + + this.submitBtn.disabled = disabled; + }); + } + + /** Reference the `id` via the static property */ + get attachmentFormId(): string { + return CipherAttachmentsComponent.attachmentFormID; + } + + /** Updates the form value when a file is selected */ + onFileChange(event: Event): void { + const fileInputEl = event.target as HTMLInputElement; + + if (fileInputEl.files && fileInputEl.files.length > 0) { + this.attachmentForm.controls.file.setValue(fileInputEl.files[0]); + } + } + + /** Save the attachments to the cipher */ + submit = async () => { + const file = this.attachmentForm.value.file; + if (file === null) { + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("selectFile"), + }); + return; + } + + if (file.size > 524288000) { + // 500 MB + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("maxFileSize"), + }); + return; + } + + try { + this.cipherDomain = await this.cipherService.saveAttachmentWithServer( + this.cipherDomain, + file, + ); + + // re-decrypt the cipher to update the attachments + this.cipher = await this.cipherDomain.decrypt( + await this.cipherService.getKeyForCipherKeyDecryption(this.cipherDomain), + ); + + // Reset reactive form and input element + this.fileInput.nativeElement.value = ""; + this.attachmentForm.controls.file.setValue(null); + + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("attachmentSaved"), + }); + + this.onUploadSuccess.emit(); + } catch (e) { + this.logService.error(e); + } + }; + + /** Removes the attachment from the cipher */ + removeAttachment(attachment: AttachmentView) { + const index = this.cipher.attachments.indexOf(attachment); + + if (index > -1) { + this.cipher.attachments.splice(index, 1); + } + } +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.html b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.html new file mode 100644 index 00000000000..38ece650b72 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.html @@ -0,0 +1,9 @@ + diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.spec.ts new file mode 100644 index 00000000000..749093902d7 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.spec.ts @@ -0,0 +1,105 @@ +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 { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; +import { DialogService, ToastService } from "@bitwarden/components"; + +import { DeleteAttachmentComponent } from "./delete-attachment.component"; + +describe("DeleteAttachmentComponent", () => { + let component: DeleteAttachmentComponent; + let fixture: ComponentFixture; + const showToast = jest.fn(); + const attachment = { + id: "222-3333-4444", + url: "attachment-url", + fileName: "attachment-filename", + size: "1234", + } as AttachmentView; + + const deleteAttachmentWithServer = jest.fn().mockResolvedValue(null); + const openSimpleDialog = jest.fn().mockResolvedValue(true); + + beforeEach(async () => { + deleteAttachmentWithServer.mockClear(); + showToast.mockClear(); + openSimpleDialog.mockClear().mockResolvedValue(true); + + await TestBed.configureTestingModule({ + imports: [DeleteAttachmentComponent], + providers: [ + { + provide: CipherService, + useValue: { deleteAttachmentWithServer }, + }, + { + provide: ToastService, + useValue: { showToast }, + }, + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: LogService, useValue: mock() }, + ], + }) + .overrideProvider(DialogService, { + useValue: { + openSimpleDialog, + }, + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DeleteAttachmentComponent); + component = fixture.componentInstance; + component.cipherId = "5555-444-3333"; + component.attachment = attachment; + fixture.detectChanges(); + }); + + it("renders delete button", () => { + const deleteButton = fixture.debugElement.query(By.css("button")); + + expect(deleteButton.attributes["title"]).toBe("deleteAttachmentName"); + }); + + it("does not delete when the user cancels the dialog", async () => { + openSimpleDialog.mockResolvedValue(false); + + await component.delete(); + + expect(openSimpleDialog).toHaveBeenCalledWith({ + title: { key: "deleteAttachment" }, + content: { key: "permanentlyDeleteAttachmentConfirmation" }, + type: "warning", + }); + + expect(deleteAttachmentWithServer).not.toHaveBeenCalled(); + }); + + it("deletes the attachment", async () => { + await component.delete(); + + expect(openSimpleDialog).toHaveBeenCalledWith({ + title: { key: "deleteAttachment" }, + content: { key: "permanentlyDeleteAttachmentConfirmation" }, + type: "warning", + }); + + // Called with cipher id and attachment id + expect(deleteAttachmentWithServer).toHaveBeenCalledWith("5555-444-3333", "222-3333-4444"); + }); + + it("shows toast message on successful deletion", async () => { + await component.delete(); + + expect(showToast).toHaveBeenCalledWith({ + variant: "success", + title: null, + message: "deletedAttachment", + }); + }); +}); diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.ts new file mode 100644 index 00000000000..932b2df2e17 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/delete-attachment/delete-attachment.component.ts @@ -0,0 +1,66 @@ +import { CommonModule } from "@angular/common"; +import { Component, EventEmitter, Input, Output } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; +import { + AsyncActionsModule, + ButtonModule, + DialogService, + IconButtonModule, + ToastService, +} from "@bitwarden/components"; + +@Component({ + standalone: true, + selector: "app-delete-attachment", + templateUrl: "./delete-attachment.component.html", + imports: [AsyncActionsModule, CommonModule, JslibModule, ButtonModule, IconButtonModule], +}) +export class DeleteAttachmentComponent { + /** Id of the cipher associated with the attachment */ + @Input({ required: true }) cipherId: string; + + /** The attachment that is can be deleted */ + @Input({ required: true }) attachment: AttachmentView; + + /** Emits when the attachment is successfully deleted */ + @Output() onDeletionSuccess = new EventEmitter(); + + constructor( + private toastService: ToastService, + private i18nService: I18nService, + private cipherService: CipherService, + private logService: LogService, + private dialogService: DialogService, + ) {} + + delete = async () => { + const confirmed = await this.dialogService.openSimpleDialog({ + title: { key: "deleteAttachment" }, + content: { key: "permanentlyDeleteAttachmentConfirmation" }, + type: "warning", + }); + + if (!confirmed) { + return; + } + + try { + await this.cipherService.deleteAttachmentWithServer(this.cipherId, this.attachment.id); + + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("deletedAttachment"), + }); + + this.onDeletionSuccess.emit(); + } catch (e) { + this.logService.error(e); + } + }; +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.html b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.html new file mode 100644 index 00000000000..e6a20ba044b --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.html @@ -0,0 +1,8 @@ + diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.spec.ts new file mode 100644 index 00000000000..45c9e7fb377 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.spec.ts @@ -0,0 +1,144 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { By } from "@angular/platform-browser"; +import { mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; +import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; +import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; +import { StateProvider } from "@bitwarden/common/platform/state"; +import { CipherType } from "@bitwarden/common/vault/enums"; +import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; + +import { ToastService } from "../../../../../../../../../../libs/components/src/toast"; + +import { DownloadAttachmentComponent } from "./download-attachment.component"; + +class MockRequest { + constructor(public url: string) {} +} + +describe("DownloadAttachmentComponent", () => { + let component: DownloadAttachmentComponent; + let fixture: ComponentFixture; + const activeUserId$ = new BehaviorSubject("888-333-222-222"); + const showToast = jest.fn(); + const getAttachmentData = jest + .fn() + .mockResolvedValue({ url: "https://www.downloadattachement.com" }); + const download = jest.fn(); + + const attachment = { + id: "222-3333-4444", + url: "https://www.attachment.com", + fileName: "attachment-filename", + size: "1234", + } as AttachmentView; + + const cipherView = { + id: "5555-444-3333", + type: CipherType.Login, + name: "Test Login", + login: { + username: "username", + password: "password", + }, + } as CipherView; + + beforeEach(async () => { + showToast.mockClear(); + getAttachmentData.mockClear(); + download.mockClear(); + + await TestBed.configureTestingModule({ + imports: [DownloadAttachmentComponent], + providers: [ + { provide: EncryptService, useValue: mock() }, + { provide: CryptoService, useValue: mock() }, + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: StateProvider, useValue: { activeUserId$ } }, + { provide: ToastService, useValue: { showToast } }, + { provide: ApiService, useValue: { getAttachmentData } }, + { provide: FileDownloadService, useValue: { download } }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DownloadAttachmentComponent); + component = fixture.componentInstance; + component.attachment = attachment; + component.cipher = cipherView; + fixture.detectChanges(); + }); + + it("renders delete button", () => { + const deleteButton = fixture.debugElement.query(By.css("button")); + + expect(deleteButton.attributes["title"]).toBe("downloadAttachmentName"); + }); + + describe("download attachment", () => { + let fetchMock: jest.Mock; + + beforeEach(() => { + fetchMock = jest.fn().mockResolvedValue({}); + global.fetch = fetchMock; + // Request is not defined in the Jest runtime + // eslint-disable-next-line no-global-assign + Request = MockRequest as any; + }); + + it("uses the attachment url when available when getAttachmentData returns a 404", async () => { + getAttachmentData.mockRejectedValue(new ErrorResponse({}, 404)); + + await component.download(); + + expect(fetchMock).toHaveBeenCalledWith({ url: attachment.url }); + }); + + it("calls file download service with the attachment url", async () => { + getAttachmentData.mockResolvedValue({ url: "https://www.downloadattachement.com" }); + fetchMock.mockResolvedValue({ status: 200 }); + EncArrayBuffer.fromResponse = jest.fn().mockResolvedValue({}); + + await component.download(); + + expect(download).toHaveBeenCalledWith({ blobData: undefined, fileName: attachment.fileName }); + }); + + describe("errors", () => { + it("shows an error toast when fetch fails", async () => { + getAttachmentData.mockResolvedValue({ url: "https://www.downloadattachement.com" }); + fetchMock.mockResolvedValue({ status: 500 }); + + await component.download(); + + expect(showToast).toHaveBeenCalledWith({ + message: "errorOccurred", + title: null, + variant: "error", + }); + }); + + it("shows an error toast when EncArrayBuffer fails", async () => { + getAttachmentData.mockResolvedValue({ url: "https://www.downloadattachement.com" }); + fetchMock.mockResolvedValue({ status: 200 }); + EncArrayBuffer.fromResponse = jest.fn().mockRejectedValue({}); + + await component.download(); + + expect(showToast).toHaveBeenCalledWith({ + message: "errorOccurred", + title: null, + variant: "error", + }); + }); + }); + }); +}); diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.ts new file mode 100644 index 00000000000..528695eab45 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/cipher-attachments/download-attachment/download-attachment.component.ts @@ -0,0 +1,104 @@ +import { CommonModule } from "@angular/common"; +import { Component, Input } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { NEVER, switchMap } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; +import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; +import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; +import { StateProvider } from "@bitwarden/common/platform/state"; +import { OrganizationId } from "@bitwarden/common/types/guid"; +import { OrgKey } from "@bitwarden/common/types/key"; +import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { AsyncActionsModule, IconButtonModule, ToastService } from "@bitwarden/components"; + +@Component({ + standalone: true, + selector: "app-download-attachment", + templateUrl: "./download-attachment.component.html", + imports: [AsyncActionsModule, CommonModule, JslibModule, IconButtonModule], +}) +export class DownloadAttachmentComponent { + /** Attachment to download */ + @Input({ required: true }) attachment: AttachmentView; + + /** The cipher associated with the attachment */ + @Input({ required: true }) cipher: CipherView; + + /** The organization key if the cipher is associated with one */ + private orgKey: OrgKey | null = null; + + constructor( + private i18nService: I18nService, + private apiService: ApiService, + private fileDownloadService: FileDownloadService, + private toastService: ToastService, + private encryptService: EncryptService, + private stateProvider: StateProvider, + private cryptoService: CryptoService, + ) { + this.stateProvider.activeUserId$ + .pipe( + switchMap((userId) => (userId !== null ? this.cryptoService.orgKeys$(userId) : NEVER)), + takeUntilDestroyed(), + ) + .subscribe((data: Record | null) => { + if (data) { + this.orgKey = data[this.cipher.organizationId as OrganizationId]; + } + }); + } + + /** Download the attachment */ + download = async () => { + let url: string; + + try { + const attachmentDownloadResponse = await this.apiService.getAttachmentData( + this.cipher.id, + this.attachment.id, + ); + url = attachmentDownloadResponse.url; + } catch (e) { + if (e instanceof ErrorResponse && (e as ErrorResponse).statusCode === 404) { + url = this.attachment.url; + } else if (e instanceof ErrorResponse) { + throw new Error((e as ErrorResponse).getSingleMessage()); + } else { + throw e; + } + } + + const response = await fetch(new Request(url, { cache: "no-store" })); + if (response.status !== 200) { + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("errorOccurred"), + }); + return; + } + + try { + const encBuf = await EncArrayBuffer.fromResponse(response); + const key = this.attachment.key != null ? this.attachment.key : this.orgKey; + const decBuf = await this.encryptService.decryptToBytes(encBuf, key); + this.fileDownloadService.download({ + fileName: this.attachment.fileName, + blobData: decBuf, + }); + } catch (e) { + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("errorOccurred"), + }); + } + }; +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html new file mode 100644 index 00000000000..6b2d8eaa033 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.html @@ -0,0 +1,14 @@ + + + diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts new file mode 100644 index 00000000000..a61c3eb6dd7 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts @@ -0,0 +1,166 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { RouterTestingModule } from "@angular/router/testing"; +import { BehaviorSubject } from "rxjs"; + +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { CipherId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherType } from "@bitwarden/common/vault/enums"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { ToastService } from "@bitwarden/components"; + +import BrowserPopupUtils from "../../../../../../platform/popup/browser-popup-utils"; + +import { OpenAttachmentsComponent } from "./open-attachments.component"; + +describe("OpenAttachmentsComponent", () => { + let component: OpenAttachmentsComponent; + let fixture: ComponentFixture; + let router: Router; + const showToast = jest.fn(); + const hasPremiumFromAnySource$ = new BehaviorSubject(true); + const openCurrentPagePopout = jest + .spyOn(BrowserPopupUtils, "openCurrentPagePopout") + .mockResolvedValue(null); + const cipherView = { + id: "5555-444-3333", + type: CipherType.Login, + name: "Test Login", + login: { + username: "username", + password: "password", + }, + } as CipherView; + + const cipherDomain = { + decrypt: () => cipherView, + }; + + const org = { + name: "Test Org", + productTierType: ProductTierType.Enterprise, + } as Organization; + + const getCipher = jest.fn().mockResolvedValue(cipherDomain); + const getOrganization = jest.fn().mockResolvedValue(org); + + beforeEach(async () => { + openCurrentPagePopout.mockClear(); + getCipher.mockClear(); + showToast.mockClear(); + getOrganization.mockClear(); + + await TestBed.configureTestingModule({ + imports: [OpenAttachmentsComponent, RouterTestingModule], + providers: [ + { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: BillingAccountProfileStateService, useValue: { hasPremiumFromAnySource$ } }, + { + provide: CipherService, + useValue: { + get: getCipher, + getKeyForCipherKeyDecryption: () => Promise.resolve(null), + }, + }, + { + provide: ToastService, + useValue: { showToast }, + }, + { + provide: OrganizationService, + useValue: { get: getOrganization }, + }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(OpenAttachmentsComponent); + component = fixture.componentInstance; + component.cipherId = "5555-444-3333" as CipherId; + router = TestBed.inject(Router); + jest.spyOn(router, "navigate").mockResolvedValue(true); + fixture.detectChanges(); + }); + + it("opens attachments in new popout", async () => { + component.openAttachmentsInPopout = true; + + await component.openAttachments(); + + expect(router.navigate).not.toHaveBeenCalled(); + expect(openCurrentPagePopout).toHaveBeenCalledWith( + window, + "http:/localhost//attachments?cipherId=5555-444-3333", + ); + }); + + it("opens attachments in same window", async () => { + component.openAttachmentsInPopout = false; + + await component.openAttachments(); + + expect(openCurrentPagePopout).not.toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith(["/attachments"], { + queryParams: { cipherId: "5555-444-3333" }, + }); + }); + + it("routes the user to the premium page when they cannot access premium features", async () => { + hasPremiumFromAnySource$.next(false); + + await component.openAttachments(); + + expect(router.navigate).toHaveBeenCalledWith(["/premium"]); + }); + + describe("Free Orgs", () => { + beforeEach(() => { + component.cipherIsAPartOfFreeOrg = undefined; + }); + + it("sets `cipherIsAPartOfFreeOrg` to false when the cipher is not a part of an organization", async () => { + cipherView.organizationId = null; + + await component.ngOnInit(); + + expect(component.cipherIsAPartOfFreeOrg).toBe(false); + }); + + it("sets `cipherIsAPartOfFreeOrg` to true when the cipher is a part of a free organization", async () => { + cipherView.organizationId = "888-333-333"; + org.productTierType = ProductTierType.Free; + + await component.ngOnInit(); + + expect(component.cipherIsAPartOfFreeOrg).toBe(true); + }); + + it("sets `cipherIsAPartOfFreeOrg` to false when the organization is not free", async () => { + cipherView.organizationId = "888-333-333"; + org.productTierType = ProductTierType.Families; + + await component.ngOnInit(); + + expect(component.cipherIsAPartOfFreeOrg).toBe(false); + }); + + it("shows toast when the cipher is a part of a free org", async () => { + component.canAccessAttachments = true; + component.cipherIsAPartOfFreeOrg = true; + + await component.openAttachments(); + + expect(showToast).toHaveBeenCalledWith({ + variant: "error", + title: null, + message: "freeOrgsCannotUseAttachments", + }); + }); + }); +}); diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts new file mode 100644 index 00000000000..c203620ed61 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts @@ -0,0 +1,101 @@ +import { CommonModule } from "@angular/common"; +import { Component, Input, OnInit } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { Router } from "@angular/router"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { CipherId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { + BadgeModule, + CardComponent, + ItemModule, + ToastService, + TypographyModule, +} from "@bitwarden/components"; + +import BrowserPopupUtils from "../../../../../../platform/popup/browser-popup-utils"; + +@Component({ + standalone: true, + selector: "app-open-attachments", + templateUrl: "./open-attachments.component.html", + imports: [BadgeModule, CommonModule, ItemModule, JslibModule, TypographyModule, CardComponent], +}) +export class OpenAttachmentsComponent implements OnInit { + /** Cipher `id` */ + @Input({ required: true }) cipherId: CipherId; + + /** True when the attachments window should be opened in a popout */ + openAttachmentsInPopout = BrowserPopupUtils.inPopup(window); + + /** True when the user has access to premium or h */ + canAccessAttachments: boolean; + + /** True when the cipher is a part of a free organization */ + cipherIsAPartOfFreeOrg: boolean; + + constructor( + private router: Router, + private billingAccountProfileStateService: BillingAccountProfileStateService, + private cipherService: CipherService, + private organizationService: OrganizationService, + private toastService: ToastService, + private i18nService: I18nService, + ) { + this.billingAccountProfileStateService.hasPremiumFromAnySource$ + .pipe(takeUntilDestroyed()) + .subscribe((canAccessPremium) => { + this.canAccessAttachments = canAccessPremium; + }); + } + + async ngOnInit(): Promise { + const cipherDomain = await this.cipherService.get(this.cipherId); + const cipher = await cipherDomain.decrypt( + await this.cipherService.getKeyForCipherKeyDecryption(cipherDomain), + ); + + if (!cipher.organizationId) { + this.cipherIsAPartOfFreeOrg = false; + return; + } + + const org = await this.organizationService.get(cipher.organizationId); + + this.cipherIsAPartOfFreeOrg = org.productTierType === ProductTierType.Free; + } + + /** Routes the user to the attachments screen, if available */ + async openAttachments() { + if (!this.canAccessAttachments) { + await this.router.navigate(["/premium"]); + return; + } + + if (this.cipherIsAPartOfFreeOrg) { + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("freeOrgsCannotUseAttachments"), + }); + return; + } + + if (this.openAttachmentsInPopout) { + const destinationUrl = this.router + .createUrlTree(["/attachments"], { queryParams: { cipherId: this.cipherId } }) + .toString(); + + const currentBaseUrl = window.location.href.replace(this.router.url, ""); + + await BrowserPopupUtils.openCurrentPagePopout(window, currentBaseUrl + destinationUrl); + } else { + await this.router.navigate(["/attachments"], { queryParams: { cipherId: this.cipherId } }); + } + } +} From 1080d46aaf7f26c8eee00caf5fde598e87801637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Thu, 27 Jun 2024 12:16:04 -0400 Subject: [PATCH 024/130] [PM-9170] generator library migrations (#9812) * migrate browser to generator libraries * migrate cli to generator libraries * migrate desktop to generator libraries * migrate angular library to generator libraries * migrate web to generator libraries --- .../popup/login-via-auth-request.component.ts | 2 +- .../browser/src/auth/popup/login.component.ts | 2 +- .../src/auth/popup/register.component.ts | 2 +- apps/browser/src/auth/popup/sso.component.ts | 2 +- ...rate-password-to-clipboard-command.spec.ts | 2 +- .../generate-password-to-clipboard-command.ts | 2 +- .../src/background/commands.background.ts | 2 +- .../browser/src/background/main.background.ts | 14 ++++++------- .../popup/generator/generator.component.ts | 6 ++++-- .../password-generator-history.component.ts | 2 +- apps/cli/src/auth/commands/login.command.ts | 2 +- apps/cli/src/service-container.ts | 6 ++++-- apps/cli/src/tools/generate.command.ts | 8 ++++--- apps/cli/tsconfig.json | 4 ++++ apps/desktop/src/app/app.component.ts | 2 +- .../src/app/services/services.module.ts | 2 +- .../src/app/tools/generator.component.spec.ts | 6 ++++-- .../src/app/tools/generator.component.ts | 6 ++++-- .../password-generator-history.component.ts | 2 +- .../login/login-via-auth-request.component.ts | 2 +- .../desktop/src/auth/login/login.component.ts | 2 +- apps/desktop/src/auth/register.component.ts | 2 +- .../src/auth/set-password.component.ts | 2 +- apps/desktop/src/auth/sso.component.ts | 2 +- .../encrypted-message-handler.service.ts | 2 +- .../components/reset-password.component.ts | 2 +- apps/web/src/app/app.component.ts | 2 +- .../web/src/app/auth/login/login.component.ts | 2 +- .../register-form/register-form.component.ts | 2 +- .../settings/change-password.component.ts | 2 +- .../emergency-access-takeover.component.ts | 2 +- .../emergency-add-edit-cipher.component.ts | 2 +- apps/web/src/app/auth/sso.component.ts | 2 +- apps/web/src/app/tools/generator.component.ts | 6 ++++-- .../password-generator-history.component.ts | 2 +- .../individual-vault/add-edit.component.ts | 2 +- .../app/vault/org-vault/add-edit.component.ts | 2 +- bitwarden_license/bit-cli/tsconfig.json | 4 ++++ .../components/change-password.component.ts | 2 +- .../login-via-auth-request.component.ts | 2 +- .../src/auth/components/login.component.ts | 2 +- .../src/auth/components/register.component.ts | 2 +- .../auth/components/set-password.component.ts | 2 +- .../src/auth/components/sso.component.spec.ts | 7 +++++-- .../src/auth/components/sso.component.ts | 2 +- .../components/update-password.component.ts | 2 +- .../update-temp-password.component.ts | 2 +- .../src/services/jslib-services.module.ts | 12 +++++------ .../components/generator.component.ts | 21 ++++++++++++------- .../password-generator-history.component.ts | 6 ++---- .../models/domain/email-forwarder-options.ts | 5 ----- .../lastpass-direct-import.service.ts | 2 +- .../generator/extensions/history/package.json | 2 +- .../generator/extensions/legacy/package.json | 6 +++--- .../extensions/navigation/package.json | 2 +- 55 files changed, 109 insertions(+), 88 deletions(-) delete mode 100644 libs/common/src/tools/models/domain/email-forwarder-options.ts diff --git a/apps/browser/src/auth/popup/login-via-auth-request.component.ts b/apps/browser/src/auth/popup/login-via-auth-request.component.ts index 69d3204701e..f83062e6c97 100644 --- a/apps/browser/src/auth/popup/login-via-auth-request.component.ts +++ b/apps/browser/src/auth/popup/login-via-auth-request.component.ts @@ -21,8 +21,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ selector: "app-login-via-auth-request", diff --git a/apps/browser/src/auth/popup/login.component.ts b/apps/browser/src/auth/popup/login.component.ts index 56a9aca68c7..760db66c311 100644 --- a/apps/browser/src/auth/popup/login.component.ts +++ b/apps/browser/src/auth/popup/login.component.ts @@ -21,8 +21,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { flagEnabled } from "../../platform/flags"; diff --git a/apps/browser/src/auth/popup/register.component.ts b/apps/browser/src/auth/popup/register.component.ts index f46289f978e..61e007ac52a 100644 --- a/apps/browser/src/auth/popup/register.component.ts +++ b/apps/browser/src/auth/popup/register.component.ts @@ -13,8 +13,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ selector: "app-register", diff --git a/apps/browser/src/auth/popup/sso.component.ts b/apps/browser/src/auth/popup/sso.component.ts index 14df0d17521..33284717ab5 100644 --- a/apps/browser/src/auth/popup/sso.component.ts +++ b/apps/browser/src/auth/popup/sso.component.ts @@ -21,8 +21,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { BrowserApi } from "../../platform/browser/browser-api"; diff --git a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.spec.ts b/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.spec.ts index e3639ef81fb..522da229244 100644 --- a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.spec.ts +++ b/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.spec.ts @@ -1,7 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { AutofillSettingsService } from "@bitwarden/common/autofill/services/autofill-settings.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { setAlarmTime } from "../../platform/alarms/alarm-state"; import { BrowserApi } from "../../platform/browser/browser-api"; diff --git a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.ts b/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.ts index c46718ebad2..dadd61fbd12 100644 --- a/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.ts +++ b/apps/browser/src/autofill/clipboard/generate-password-to-clipboard-command.ts @@ -1,7 +1,7 @@ import { firstValueFrom } from "rxjs"; import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { setAlarmTime } from "../../platform/alarms/alarm-state"; diff --git a/apps/browser/src/background/commands.background.ts b/apps/browser/src/background/commands.background.ts index 10395e66e5a..f2152c7f9f4 100644 --- a/apps/browser/src/background/commands.background.ts +++ b/apps/browser/src/background/commands.background.ts @@ -2,7 +2,7 @@ import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeou import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { openUnlockPopout } from "../auth/popup/utils/auth-popout-window"; import { LockedVaultPendingNotificationsData } from "../autofill/background/abstractions/notification.background"; diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 0ea0be9ffdb..7e2b802d346 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -147,12 +147,6 @@ import { EventUploadService } from "@bitwarden/common/services/event/event-uploa import { NotificationsService } from "@bitwarden/common/services/notifications.service"; import { SearchService } from "@bitwarden/common/services/search.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vault-timeout/vault-timeout-settings.service"; -import { - legacyPasswordGenerationServiceFactory, - legacyUsernameGenerationServiceFactory, -} from "@bitwarden/common/tools/generator"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; -import { UsernameGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/username"; import { PasswordStrengthService, PasswordStrengthServiceAbstraction, @@ -179,6 +173,12 @@ import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder import { FolderService } from "@bitwarden/common/vault/services/folder/folder.service"; import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service"; +import { + legacyPasswordGenerationServiceFactory, + PasswordGenerationServiceAbstraction, + legacyUsernameGenerationServiceFactory, + UsernameGenerationServiceAbstraction, +} from "@bitwarden/generator-legacy"; import { ImportApiService, ImportApiServiceAbstraction, @@ -267,8 +267,8 @@ export default class MainBackground { collectionService: CollectionServiceAbstraction; vaultTimeoutService: VaultTimeoutService; vaultTimeoutSettingsService: VaultTimeoutSettingsServiceAbstraction; - syncService: SyncService; passwordGenerationService: PasswordGenerationServiceAbstraction; + syncService: SyncService; passwordStrengthService: PasswordStrengthServiceAbstraction; totpService: TotpServiceAbstraction; autofillService: AutofillServiceAbstraction; diff --git a/apps/browser/src/tools/popup/generator/generator.component.ts b/apps/browser/src/tools/popup/generator/generator.component.ts index cb671f7201a..8746456ec0a 100644 --- a/apps/browser/src/tools/popup/generator/generator.component.ts +++ b/apps/browser/src/tools/popup/generator/generator.component.ts @@ -8,12 +8,14 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv 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 { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; -import { UsernameGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/username"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { AddEditCipherInfo } from "@bitwarden/common/vault/types/add-edit-cipher-info"; import { ToastService } from "@bitwarden/components"; +import { + PasswordGenerationServiceAbstraction, + UsernameGenerationServiceAbstraction, +} from "@bitwarden/generator-legacy"; @Component({ selector: "app-generator", diff --git a/apps/browser/src/tools/popup/generator/password-generator-history.component.ts b/apps/browser/src/tools/popup/generator/password-generator-history.component.ts index e27c42a111b..2436ae51a7d 100644 --- a/apps/browser/src/tools/popup/generator/password-generator-history.component.ts +++ b/apps/browser/src/tools/popup/generator/password-generator-history.component.ts @@ -4,8 +4,8 @@ import { Component } from "@angular/core"; import { PasswordGeneratorHistoryComponent as BasePasswordGeneratorHistoryComponent } from "@bitwarden/angular/tools/generator/components/password-generator-history.component"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { ToastService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ selector: "app-password-generator-history", diff --git a/apps/cli/src/auth/commands/login.command.ts b/apps/cli/src/auth/commands/login.command.ts index 5e80f6faf40..3b67f955406 100644 --- a/apps/cli/src/auth/commands/login.command.ts +++ b/apps/cli/src/auth/commands/login.command.ts @@ -35,9 +35,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { NodeUtils } from "@bitwarden/node/node-utils"; import { Response } from "../../models/response"; diff --git a/apps/cli/src/service-container.ts b/apps/cli/src/service-container.ts index fe9de868226..aeb233a31da 100644 --- a/apps/cli/src/service-container.ts +++ b/apps/cli/src/service-container.ts @@ -106,8 +106,6 @@ import { EventUploadService } from "@bitwarden/common/services/event/event-uploa import { SearchService } from "@bitwarden/common/services/search.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vault-timeout/vault-timeout-settings.service"; import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service"; -import { legacyPasswordGenerationServiceFactory } from "@bitwarden/common/tools/generator"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordStrengthService, PasswordStrengthServiceAbstraction, @@ -124,6 +122,10 @@ import { CipherFileUploadService } from "@bitwarden/common/vault/services/file-u import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder-api.service"; import { FolderService } from "@bitwarden/common/vault/services/folder/folder.service"; import { TotpService } from "@bitwarden/common/vault/services/totp.service"; +import { + legacyPasswordGenerationServiceFactory, + PasswordGenerationServiceAbstraction, +} from "@bitwarden/generator-legacy"; import { ImportApiService, ImportApiServiceAbstraction, diff --git a/apps/cli/src/tools/generate.command.ts b/apps/cli/src/tools/generate.command.ts index 2bbfb02267b..2829bc51414 100644 --- a/apps/cli/src/tools/generate.command.ts +++ b/apps/cli/src/tools/generate.command.ts @@ -1,10 +1,12 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { DefaultPassphraseGenerationOptions } from "@bitwarden/common/tools/generator/passphrase"; import { DefaultPasswordGenerationOptions, + DefaultPassphraseGenerationOptions, +} from "@bitwarden/generator-core"; +import { + PasswordGeneratorOptions, PasswordGenerationServiceAbstraction, -} from "@bitwarden/common/tools/generator/password"; -import { PasswordGeneratorOptions } from "@bitwarden/common/tools/generator/password/password-generator-options"; +} from "@bitwarden/generator-legacy"; import { Response } from "../models/response"; import { StringResponse } from "../models/response/string.response"; diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index b5e9b5a1900..0a34b05496f 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -17,6 +17,10 @@ "@bitwarden/auth/angular": ["../../libs/auth/src/angular"], "@bitwarden/common/*": ["../../libs/common/src/*"], "@bitwarden/importer/core": ["../../libs/importer/src"], + "@bitwarden/generator-core": ["../../libs/tools/generator/core/src"], + "@bitwarden/generator-legacy": ["../../libs/tools/generator/extensions/legacy/src"], + "@bitwarden/generator-history": ["../../libs/tools/generator/extensions/history/src"], + "@bitwarden/generator-navigation": ["../../libs/tools/generator/extensions/navigation/src"], "@bitwarden/vault-export-core": [ "../../libs/tools/export/vault-export/vault-export-core/src" ], diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index e4fdd17dc15..e01a11b8c77 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -43,7 +43,6 @@ import { BiometricStateService } from "@bitwarden/common/platform/biometrics/bio import { clearCaches } from "@bitwarden/common/platform/misc/sequentialize"; import { StateEventRunnerService } from "@bitwarden/common/platform/state"; import { SyncService } from "@bitwarden/common/platform/sync"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserId } from "@bitwarden/common/types/guid"; import { VaultTimeout, VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -51,6 +50,7 @@ import { CollectionService } from "@bitwarden/common/vault/abstractions/collecti import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherType } from "@bitwarden/common/vault/enums"; import { DialogService, ToastOptions, ToastService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { DeleteAccountComponent } from "../auth/delete-account.component"; import { LoginApprovalComponent } from "../auth/login/login-approval.component"; diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 25d4df5f935..7a2bc6ccccc 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -56,10 +56,10 @@ import { SystemService } from "@bitwarden/common/platform/services/system.servic import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/state"; // eslint-disable-next-line import/no-restricted-paths -- Implementation for memory storage import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type"; import { CipherService as CipherServiceAbstraction } from "@bitwarden/common/vault/abstractions/cipher.service"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { PinServiceAbstraction } from "../../../../../libs/auth/src/common/abstractions"; import { DesktopAutofillSettingsService } from "../../autofill/services/desktop-autofill-settings.service"; diff --git a/apps/desktop/src/app/tools/generator.component.spec.ts b/apps/desktop/src/app/tools/generator.component.spec.ts index db8160c2025..c259b4e52ce 100644 --- a/apps/desktop/src/app/tools/generator.component.spec.ts +++ b/apps/desktop/src/app/tools/generator.component.spec.ts @@ -8,10 +8,12 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv 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 { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; -import { UsernameGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/username"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { ToastService } from "@bitwarden/components"; +import { + PasswordGenerationServiceAbstraction, + UsernameGenerationServiceAbstraction, +} from "@bitwarden/generator-legacy"; import { GeneratorComponent } from "./generator.component"; diff --git a/apps/desktop/src/app/tools/generator.component.ts b/apps/desktop/src/app/tools/generator.component.ts index 0f1443314dc..fc9ff489a1a 100644 --- a/apps/desktop/src/app/tools/generator.component.ts +++ b/apps/desktop/src/app/tools/generator.component.ts @@ -6,9 +6,11 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv 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 { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; -import { UsernameGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/username"; import { ToastService } from "@bitwarden/components"; +import { + PasswordGenerationServiceAbstraction, + UsernameGenerationServiceAbstraction, +} from "@bitwarden/generator-legacy"; @Component({ selector: "app-generator", diff --git a/apps/desktop/src/app/tools/password-generator-history.component.ts b/apps/desktop/src/app/tools/password-generator-history.component.ts index 07ebe5fb4bd..0c7c9c4e221 100644 --- a/apps/desktop/src/app/tools/password-generator-history.component.ts +++ b/apps/desktop/src/app/tools/password-generator-history.component.ts @@ -3,8 +3,8 @@ import { Component } from "@angular/core"; import { PasswordGeneratorHistoryComponent as BasePasswordGeneratorHistoryComponent } from "@bitwarden/angular/tools/generator/components/password-generator-history.component"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { ToastService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ selector: "app-password-generator-history", diff --git a/apps/desktop/src/auth/login/login-via-auth-request.component.ts b/apps/desktop/src/auth/login/login-via-auth-request.component.ts index 40d41f22361..7a8dfcbcda7 100644 --- a/apps/desktop/src/auth/login/login-via-auth-request.component.ts +++ b/apps/desktop/src/auth/login/login-via-auth-request.component.ts @@ -22,8 +22,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { EnvironmentComponent } from "../environment.component"; diff --git a/apps/desktop/src/auth/login/login.component.ts b/apps/desktop/src/auth/login/login.component.ts index fd57e9015b1..d37e9961b2f 100644 --- a/apps/desktop/src/auth/login/login.component.ts +++ b/apps/desktop/src/auth/login/login.component.ts @@ -23,8 +23,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { EnvironmentComponent } from "../environment.component"; diff --git a/apps/desktop/src/auth/register.component.ts b/apps/desktop/src/auth/register.component.ts index 82b815aa186..be44c276485 100644 --- a/apps/desktop/src/auth/register.component.ts +++ b/apps/desktop/src/auth/register.component.ts @@ -14,8 +14,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; const BroadcasterSubscriptionId = "RegisterComponent"; diff --git a/apps/desktop/src/auth/set-password.component.ts b/apps/desktop/src/auth/set-password.component.ts index feea5edd867..3012f646036 100644 --- a/apps/desktop/src/auth/set-password.component.ts +++ b/apps/desktop/src/auth/set-password.component.ts @@ -19,10 +19,10 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; const BroadcasterSubscriptionId = "SetPasswordComponent"; diff --git a/apps/desktop/src/auth/sso.component.ts b/apps/desktop/src/auth/sso.component.ts index cc261f1235c..234ebc85cee 100644 --- a/apps/desktop/src/auth/sso.component.ts +++ b/apps/desktop/src/auth/sso.component.ts @@ -17,8 +17,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ selector: "app-sso", diff --git a/apps/desktop/src/services/encrypted-message-handler.service.ts b/apps/desktop/src/services/encrypted-message-handler.service.ts index 4512e175ceb..519bd91064c 100644 --- a/apps/desktop/src/services/encrypted-message-handler.service.ts +++ b/apps/desktop/src/services/encrypted-message-handler.service.ts @@ -6,13 +6,13 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { DecryptedCommandData } from "../models/native-messaging/decrypted-command-data"; import { CredentialCreatePayload } from "../models/native-messaging/encrypted-message-payloads/credential-create-payload"; diff --git a/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts b/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts index 641d1f2e954..291b0269427 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts @@ -17,8 +17,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic 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 { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { OrganizationUserResetPasswordService } from "../services/organization-user-reset-password/organization-user-reset-password.service"; diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index f9d290de796..1c5527504d9 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -36,12 +36,12 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { StateEventRunnerService } from "@bitwarden/common/platform/state"; import { SyncService } from "@bitwarden/common/platform/sync"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { DialogService, ToastOptions, ToastService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { PolicyListService } from "./admin-console/core/policy-list.service"; import { diff --git a/apps/web/src/app/auth/login/login.component.ts b/apps/web/src/app/auth/login/login.component.ts index a3ff8bef436..d7d34a4c2fd 100644 --- a/apps/web/src/app/auth/login/login.component.ts +++ b/apps/web/src/app/auth/login/login.component.ts @@ -26,8 +26,8 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi 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 { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { flagEnabled } from "../../../utils/flags"; import { RouterService, StateService } from "../../core"; diff --git a/apps/web/src/app/auth/register-form/register-form.component.ts b/apps/web/src/app/auth/register-form/register-form.component.ts index 4532cf14050..ce1255e023a 100644 --- a/apps/web/src/app/auth/register-form/register-form.component.ts +++ b/apps/web/src/app/auth/register-form/register-form.component.ts @@ -17,8 +17,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { AcceptOrganizationInviteService } from "../organization-invite/accept-organization.service"; diff --git a/apps/web/src/app/auth/settings/change-password.component.ts b/apps/web/src/app/auth/settings/change-password.component.ts index 95bdb706243..aa27588691f 100644 --- a/apps/web/src/app/auth/settings/change-password.component.ts +++ b/apps/web/src/app/auth/settings/change-password.component.ts @@ -17,11 +17,11 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { UserKeyRotationService } from "../key-rotation/user-key-rotation.service"; diff --git a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts index 6115b4bac1a..a3d856aa697 100644 --- a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts @@ -15,8 +15,8 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { KdfType } from "@bitwarden/common/platform/enums"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { EmergencyAccessService } from "../../../emergency-access"; diff --git a/apps/web/src/app/auth/settings/emergency-access/view/emergency-add-edit-cipher.component.ts b/apps/web/src/app/auth/settings/emergency-access/view/emergency-add-edit-cipher.component.ts index 1e070d42ab2..f3003151f4c 100644 --- a/apps/web/src/app/auth/settings/emergency-access/view/emergency-add-edit-cipher.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/view/emergency-add-edit-cipher.component.ts @@ -12,7 +12,6 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password/"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; @@ -20,6 +19,7 @@ import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folde import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { PasswordRepromptService } from "@bitwarden/vault"; import { AddEditComponent as BaseAddEditComponent } from "../../../../vault/individual-vault/add-edit.component"; diff --git a/apps/web/src/app/auth/sso.component.ts b/apps/web/src/app/auth/sso.component.ts index 731cade3746..69bfd0a8c48 100644 --- a/apps/web/src/app/auth/sso.component.ts +++ b/apps/web/src/app/auth/sso.component.ts @@ -24,7 +24,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ selector: "app-sso", diff --git a/apps/web/src/app/tools/generator.component.ts b/apps/web/src/app/tools/generator.component.ts index 0a39228f3d6..f462e8fa4bf 100644 --- a/apps/web/src/app/tools/generator.component.ts +++ b/apps/web/src/app/tools/generator.component.ts @@ -6,9 +6,11 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv 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 { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; -import { UsernameGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/username"; import { DialogService, ToastService } from "@bitwarden/components"; +import { + PasswordGenerationServiceAbstraction, + UsernameGenerationServiceAbstraction, +} from "@bitwarden/generator-legacy"; import { PasswordGeneratorHistoryComponent } from "./password-generator-history.component"; diff --git a/apps/web/src/app/tools/password-generator-history.component.ts b/apps/web/src/app/tools/password-generator-history.component.ts index 07ebe5fb4bd..0c7c9c4e221 100644 --- a/apps/web/src/app/tools/password-generator-history.component.ts +++ b/apps/web/src/app/tools/password-generator-history.component.ts @@ -3,8 +3,8 @@ import { Component } from "@angular/core"; import { PasswordGeneratorHistoryComponent as BasePasswordGeneratorHistoryComponent } from "@bitwarden/angular/tools/generator/components/password-generator-history.component"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { ToastService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ selector: "app-password-generator-history", diff --git a/apps/web/src/app/vault/individual-vault/add-edit.component.ts b/apps/web/src/app/vault/individual-vault/add-edit.component.ts index d9000e4acc4..7a96bff0392 100644 --- a/apps/web/src/app/vault/individual-vault/add-edit.component.ts +++ b/apps/web/src/app/vault/individual-vault/add-edit.component.ts @@ -16,7 +16,6 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; @@ -25,6 +24,7 @@ import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { Launchable } from "@bitwarden/common/vault/interfaces/launchable"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { PasswordRepromptService } from "@bitwarden/vault"; @Component({ diff --git a/apps/web/src/app/vault/org-vault/add-edit.component.ts b/apps/web/src/app/vault/org-vault/add-edit.component.ts index 9c7c3c30f32..c0a83ed74cb 100644 --- a/apps/web/src/app/vault/org-vault/add-edit.component.ts +++ b/apps/web/src/app/vault/org-vault/add-edit.component.ts @@ -13,7 +13,6 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; @@ -22,6 +21,7 @@ import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { CipherData } from "@bitwarden/common/vault/models/data/cipher.data"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { PasswordRepromptService } from "@bitwarden/vault"; import { AddEditComponent as BaseAddEditComponent } from "../individual-vault/add-edit.component"; diff --git a/bitwarden_license/bit-cli/tsconfig.json b/bitwarden_license/bit-cli/tsconfig.json index e8a57e5eb04..20d136df2a5 100644 --- a/bitwarden_license/bit-cli/tsconfig.json +++ b/bitwarden_license/bit-cli/tsconfig.json @@ -18,6 +18,10 @@ "@bitwarden/auth/angular": ["../../libs/auth/src/angular"], "@bitwarden/common/*": ["../../libs/common/src/*"], "@bitwarden/importer/core": ["../../libs/importer/src"], + "@bitwarden/generator-core": ["../../libs/tools/generator/core/src"], + "@bitwarden/generator-legacy": ["../../libs/tools/generator/extensions/legacy/src"], + "@bitwarden/generator-history": ["../../libs/tools/generator/extensions/history/src"], + "@bitwarden/generator-navigation": ["../../libs/tools/generator/extensions/navigation/src"], "@bitwarden/vault-export-core": [ "../../libs/tools/export/vault-export/vault-export-core/src" ], diff --git a/libs/angular/src/auth/components/change-password.component.ts b/libs/angular/src/auth/components/change-password.component.ts index 975090b3896..5e9b31138e0 100644 --- a/libs/angular/src/auth/components/change-password.component.ts +++ b/libs/angular/src/auth/components/change-password.component.ts @@ -14,9 +14,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserKey, MasterKey } from "@bitwarden/common/types/key"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { PasswordColorText } from "../../tools/password-strength/password-strength.component"; diff --git a/libs/angular/src/auth/components/login-via-auth-request.component.ts b/libs/angular/src/auth/components/login-via-auth-request.component.ts index f898fa4ee8d..91e815cf783 100644 --- a/libs/angular/src/auth/components/login-via-auth-request.component.ts +++ b/libs/angular/src/auth/components/login-via-auth-request.component.ts @@ -31,8 +31,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserId } from "@bitwarden/common/types/guid"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { CaptchaProtectedComponent } from "./captcha-protected.component"; diff --git a/libs/angular/src/auth/components/login.component.ts b/libs/angular/src/auth/components/login.component.ts index 7fb23ca4600..4466a106a56 100644 --- a/libs/angular/src/auth/components/login.component.ts +++ b/libs/angular/src/auth/components/login.component.ts @@ -24,7 +24,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { AllValidationErrors, diff --git a/libs/angular/src/auth/components/register.component.ts b/libs/angular/src/auth/components/register.component.ts index 533920d13c8..366290a79ad 100644 --- a/libs/angular/src/auth/components/register.component.ts +++ b/libs/angular/src/auth/components/register.component.ts @@ -17,8 +17,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { AllValidationErrors, diff --git a/libs/angular/src/auth/components/set-password.component.ts b/libs/angular/src/auth/components/set-password.component.ts index b08c7967532..33c2e0dd242 100644 --- a/libs/angular/src/auth/components/set-password.component.ts +++ b/libs/angular/src/auth/components/set-password.component.ts @@ -28,11 +28,11 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { HashPurpose } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; diff --git a/libs/angular/src/auth/components/sso.component.spec.ts b/libs/angular/src/auth/components/sso.component.spec.ts index ae644028f99..dff6268f393 100644 --- a/libs/angular/src/auth/components/sso.component.spec.ts +++ b/libs/angular/src/auth/components/sso.component.spec.ts @@ -27,8 +27,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserId } from "@bitwarden/common/types/guid"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { SsoComponent } from "./sso.component"; // test component that extends the SsoComponent @@ -201,7 +201,10 @@ describe("SsoComponent", () => { { provide: ApiService, useValue: mockApiService }, { provide: CryptoFunctionService, useValue: mockCryptoFunctionService }, { provide: EnvironmentService, useValue: mockEnvironmentService }, - { provide: PasswordGenerationServiceAbstraction, useValue: mockPasswordGenerationService }, + { + provide: PasswordGenerationServiceAbstraction, + useValue: mockPasswordGenerationService, + }, { provide: UserDecryptionOptionsServiceAbstraction, diff --git a/libs/angular/src/auth/components/sso.component.ts b/libs/angular/src/auth/components/sso.component.ts index 30815beef8a..2c6f7b29cbd 100644 --- a/libs/angular/src/auth/components/sso.component.ts +++ b/libs/angular/src/auth/components/sso.component.ts @@ -25,7 +25,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Directive() export class SsoComponent { diff --git a/libs/angular/src/auth/components/update-password.component.ts b/libs/angular/src/auth/components/update-password.component.ts index 62e0359038c..661e50e887a 100644 --- a/libs/angular/src/auth/components/update-password.component.ts +++ b/libs/angular/src/auth/components/update-password.component.ts @@ -18,9 +18,9 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; diff --git a/libs/angular/src/auth/components/update-temp-password.component.ts b/libs/angular/src/auth/components/update-temp-password.component.ts index e797c93be1e..bb9c23b1cc0 100644 --- a/libs/angular/src/auth/components/update-temp-password.component.ts +++ b/libs/angular/src/auth/components/update-temp-password.component.ts @@ -21,10 +21,10 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService } from "@bitwarden/components"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 388a149bfa1..86ccce4e004 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -202,12 +202,6 @@ import { NotificationsService } from "@bitwarden/common/services/notifications.s import { SearchService } from "@bitwarden/common/services/search.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vault-timeout/vault-timeout-settings.service"; import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service"; -import { - legacyPasswordGenerationServiceFactory, - legacyUsernameGenerationServiceFactory, -} from "@bitwarden/common/tools/generator"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; -import { UsernameGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/username"; import { PasswordStrengthService, PasswordStrengthServiceAbstraction, @@ -239,6 +233,12 @@ import { FolderService } from "@bitwarden/common/vault/services/folder/folder.se import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service"; import { ToastService } from "@bitwarden/components"; +import { + legacyPasswordGenerationServiceFactory, + legacyUsernameGenerationServiceFactory, + PasswordGenerationServiceAbstraction, + UsernameGenerationServiceAbstraction, +} from "@bitwarden/generator-legacy"; import { ImportApiService, ImportApiServiceAbstraction, diff --git a/libs/angular/src/tools/generator/components/generator.component.ts b/libs/angular/src/tools/generator/components/generator.component.ts index 1f7c931df30..e17ac7071cd 100644 --- a/libs/angular/src/tools/generator/components/generator.component.ts +++ b/libs/angular/src/tools/generator/components/generator.component.ts @@ -8,18 +8,23 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv 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 { GeneratorType } from "@bitwarden/common/tools/generator/generator-type"; +import { ToastService } from "@bitwarden/components"; +import { + GeneratorType, + DefaultPasswordBoundaries as DefaultBoundaries, +} from "@bitwarden/generator-core"; import { PasswordGenerationServiceAbstraction, - PasswordGeneratorOptions, -} from "@bitwarden/common/tools/generator/password"; -import { DefaultBoundaries } from "@bitwarden/common/tools/generator/password/password-generator-options-evaluator"; -import { UsernameGenerationServiceAbstraction, UsernameGeneratorOptions, -} from "@bitwarden/common/tools/generator/username"; -import { EmailForwarderOptions } from "@bitwarden/common/tools/models/domain/email-forwarder-options"; -import { ToastService } from "@bitwarden/components"; + PasswordGeneratorOptions, +} from "@bitwarden/generator-legacy"; + +export class EmailForwarderOptions { + name: string; + value: string; + validForSelfHosted: boolean; +} @Directive() export class GeneratorComponent implements OnInit, OnDestroy { diff --git a/libs/angular/src/tools/generator/components/password-generator-history.component.ts b/libs/angular/src/tools/generator/components/password-generator-history.component.ts index f0438a9a5a3..5eea8cec282 100644 --- a/libs/angular/src/tools/generator/components/password-generator-history.component.ts +++ b/libs/angular/src/tools/generator/components/password-generator-history.component.ts @@ -2,11 +2,9 @@ import { Directive, OnInit } from "@angular/core"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { - GeneratedPasswordHistory, - PasswordGenerationServiceAbstraction, -} from "@bitwarden/common/tools/generator/password"; import { ToastService } from "@bitwarden/components"; +import { GeneratedPasswordHistory } from "@bitwarden/generator-history"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Directive() export class PasswordGeneratorHistoryComponent implements OnInit { diff --git a/libs/common/src/tools/models/domain/email-forwarder-options.ts b/libs/common/src/tools/models/domain/email-forwarder-options.ts deleted file mode 100644 index 61449a8c70c..00000000000 --- a/libs/common/src/tools/models/domain/email-forwarder-options.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class EmailForwarderOptions { - name: string; - value: string; - validForSelfHosted: boolean; -} diff --git a/libs/importer/src/components/lastpass/lastpass-direct-import.service.ts b/libs/importer/src/components/lastpass/lastpass-direct-import.service.ts index 678c4d35dac..5f31b0af44a 100644 --- a/libs/importer/src/components/lastpass/lastpass-direct-import.service.ts +++ b/libs/importer/src/components/lastpass/lastpass-direct-import.service.ts @@ -10,7 +10,7 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { DialogService } from "../../../../components/src/dialog"; import { ClientInfo, Vault } from "../../importers/lastpass/access"; diff --git a/libs/tools/generator/extensions/history/package.json b/libs/tools/generator/extensions/history/package.json index 8ce2d920df9..00342fe435a 100644 --- a/libs/tools/generator/extensions/history/package.json +++ b/libs/tools/generator/extensions/history/package.json @@ -19,6 +19,6 @@ }, "dependencies": { "@bitwarden/common": "file:../../../common", - "@bitwarden/generator-core": "file:../core" + "@bitwarden/generator-core": "file:../../core" } } diff --git a/libs/tools/generator/extensions/legacy/package.json b/libs/tools/generator/extensions/legacy/package.json index c97e817ce22..0a257c67a49 100644 --- a/libs/tools/generator/extensions/legacy/package.json +++ b/libs/tools/generator/extensions/legacy/package.json @@ -19,8 +19,8 @@ }, "dependencies": { "@bitwarden/common": "file:../../../common", - "@bitwarden/generator-core": "file:../core", - "@bitwarden/generator-history": "file:../extensions/history", - "@bitwarden/generator-navigation": "file:../extensions/navigation" + "@bitwarden/generator-core": "file:../../core", + "@bitwarden/generator-history": "file:../history", + "@bitwarden/generator-navigation": "file:../navigation" } } diff --git a/libs/tools/generator/extensions/navigation/package.json b/libs/tools/generator/extensions/navigation/package.json index ba66ce3a79e..c929f46ed0f 100644 --- a/libs/tools/generator/extensions/navigation/package.json +++ b/libs/tools/generator/extensions/navigation/package.json @@ -19,6 +19,6 @@ }, "dependencies": { "@bitwarden/common": "file:../../../common", - "@bitwarden/generator-core": "file:../core" + "@bitwarden/generator-core": "file:../../core" } } From 3c8eeb4420d3289d90f72f045cb09ffcd25824df Mon Sep 17 00:00:00 2001 From: Addison Beck Date: Thu, 27 Jun 2024 12:47:52 -0400 Subject: [PATCH 025/130] Remove the `bit` prefix from Bitwarden License managed build artifacts (#9855) * Rename `license_type.prefix` to `license_type.build_prefix` * Introduce `license_type.artifact_prefix` * Remove the `bit` prefix from Bitwarden License managed build artifacts * Update the release job to download the correct artifacts * Update .github/workflows/build-cli.yml Co-authored-by: Joseph Flinn <58369717+joseph-flinn@users.noreply.github.com> * Update .github/workflows/build-cli.yml Co-authored-by: Joseph Flinn <58369717+joseph-flinn@users.noreply.github.com> * Update .github/workflows/build-cli.yml Co-authored-by: Joseph Flinn <58369717+joseph-flinn@users.noreply.github.com> --------- Co-authored-by: Joseph Flinn <58369717+joseph-flinn@users.noreply.github.com> --- .github/workflows/build-cli.yml | 64 +++++++++++++++---------------- .github/workflows/release-cli.yml | 12 +++--- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index 1c2693f2dec..ad2ac539715 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -71,8 +71,8 @@ jobs: ] license_type: [ - { prefix: "oss", readable: "open source license" }, - { prefix: "bit", readable: "commercial license"} + { build_prefix: "oss", artifact_prefix: "-oss", readable: "open source license" }, + { build_prefix: "bit", artifact_prefix: "", readable: "commercial license"} ] runs-on: ${{ matrix.os.distro }} needs: @@ -104,16 +104,16 @@ jobs: working-directory: ./ - name: Build & Package Unix - run: npm run dist:${{ matrix.license_type.prefix }}:${{ env.SHORT_RUNNER_OS }} --quiet + run: npm run dist:${{ matrix.license_type.build_prefix }}:${{ env.SHORT_RUNNER_OS }} --quiet - name: Zip Unix run: | - cd ./dist/${{ matrix.license_type.prefix }}/${{ env.LOWER_RUNNER_OS }} - zip ../../bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip ./bw + cd ./dist/${{ matrix.license_type.build_prefix }}/${{ env.LOWER_RUNNER_OS }} + zip ../../bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip ./bw - name: Version Test run: | - unzip "./dist/bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip" -d "./test" + unzip "./dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip" -d "./test" testVersion=$(./test/bw -v) echo "version: $_PACKAGE_VERSION" echo "testVersion: $testVersion" @@ -125,21 +125,22 @@ jobs: - name: Create checksums Unix run: | cd ./dist - shasum -a 256 bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip \ - | awk '{split($0, a); print a[1]}' > bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt + shasum -a 256 bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip \ + | awk '{split($0, a); print a[1]}' > bw${{ + matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt - name: Upload unix zip asset uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip - path: apps/cli/dist/bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip + name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip + path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip if-no-files-found: error - name: Upload unix checksum asset uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt - path: apps/cli/dist/bw-${{ matrix.license_type.prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt + name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt + path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt if-no-files-found: error cli-windows: @@ -148,8 +149,8 @@ jobs: matrix: license_type: [ - { prefix: "oss", readable: "open source license" }, - { prefix: "bit", readable: "commercial license"} + { build_prefix: "oss", artifact_prefix: "-oss", readable: "open source license" }, + { build_prefix: "bit", artifact_prefix: "", readable: "commercial license"} ] runs-on: windows-2022 needs: @@ -236,26 +237,26 @@ jobs: working-directory: ./ - name: Build & Package Windows - run: npm run dist:${{ matrix.license_type.prefix }}:win --quiet + run: npm run dist:${{ matrix.license_type.build_prefix }}:win --quiet - name: Package Chocolatey shell: pwsh - if: ${{ matrix.license_type.prefix }} == 'bit' + if: ${{ matrix.license_type.build_prefix }} == 'bit' run: | Copy-Item -Path stores/chocolatey -Destination dist/chocolatey -Recurse - Copy-Item dist/${{ matrix.license_type.prefix }}/windows/bw.exe -Destination dist/chocolatey/tools + Copy-Item dist/${{ matrix.license_type.build_prefix }}/windows/bw.exe -Destination dist/chocolatey/tools Copy-Item ${{ github.workspace }}/LICENSE.txt -Destination dist/chocolatey/tools choco pack dist/chocolatey/bitwarden-cli.nuspec --version ${{ env._PACKAGE_VERSION }} --out dist/chocolatey - name: Zip Windows shell: cmd - run: 7z a ./dist/bw-${{ matrix.license_type.prefix }}-windows-%_PACKAGE_VERSION%.zip ./dist/${{ matrix.license_type.prefix }}/windows/bw.exe + run: 7z a ./dist/bw${{ matrix.license_type.artifact_prefix}}-windows-%_PACKAGE_VERSION%.zip ./dist/${{ matrix.license_type.build_prefix }}/windows/bw.exe - name: Version Test run: | dir ./dist/ - Expand-Archive -Path "./dist/bw-${{ matrix.license_type.prefix }}-windows-${env:_PACKAGE_VERSION}.zip" -DestinationPath "./test/${{ matrix.license_type.prefix }}/windows" - $testVersion = Invoke-Expression '& ./test/${{ matrix.license_type.prefix }}/windows/bw.exe -v' + Expand-Archive -Path "./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${env:_PACKAGE_VERSION}.zip" -DestinationPath "./test/${{ matrix.license_type.build_prefix }}/windows" + $testVersion = Invoke-Expression '& ./test/${{ matrix.license_type.build_prefix }}/windows/bw.exe -v' echo "version: $env:_PACKAGE_VERSION" echo "testVersion: $testVersion" if($testVersion -ne $env:_PACKAGE_VERSION) { @@ -264,25 +265,25 @@ jobs: - name: Create checksums Windows run: | - checksum -f="./dist/bw-${{ matrix.license_type.prefix }}-windows-${env:_PACKAGE_VERSION}.zip" ` - -t sha256 | Out-File -Encoding ASCII ./dist/bw-${{ matrix.license_type.prefix }}-windows-sha256-${env:_PACKAGE_VERSION}.txt + checksum -f="./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${env:_PACKAGE_VERSION}.zip" ` + -t sha256 | Out-File -Encoding ASCII ./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${env:_PACKAGE_VERSION}.txt - name: Upload windows zip asset uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: bw-${{ matrix.license_type.prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip - path: apps/cli/dist/bw-${{ matrix.license_type.prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip + name: bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip + path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip if-no-files-found: error - name: Upload windows checksum asset uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: bw-${{ matrix.license_type.prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt - path: apps/cli/dist/bw-${{ matrix.license_type.prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt + name: bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt + path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt if-no-files-found: error - name: Upload Chocolatey asset - if: matrix.license_type.prefix == 'bit' + if: matrix.license_type.build_prefix == 'bit' uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg @@ -290,7 +291,7 @@ jobs: if-no-files-found: error - name: Upload NPM Build Directory asset - if: matrix.license_type.prefix == 'bit' + if: matrix.license_type.build_prefix == 'bit' uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip @@ -320,14 +321,9 @@ jobs: - name: Get bw linux cli uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 with: - name: bw-bit-linux-${{ env._PACKAGE_VERSION }}.zip + name: bw-linux-${{ env._PACKAGE_VERSION }}.zip path: apps/cli/dist/snap - - name: Rename snap artifact - run: | - cd dist/snap - mv bw-bit-linux-${{ env._PACKAGE_VERSION }}.zip bw-linux-${{ env._PACKAGE_VERSION }}.zip - - name: Setup Snap Package run: | cp -r stores/snap/* -t dist/snap diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index 5b511cd1d95..6d56c3be831 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -102,16 +102,16 @@ jobs: with: artifacts: "apps/cli/bw-oss-windows-${{ env.PKG_VERSION }}.zip, apps/cli/bw-oss-windows-sha256-${{ env.PKG_VERSION }}.txt, - apps/cli/bw-bit-windows-${{ env.PKG_VERSION }}.zip, - apps/cli/bw-bit-windows-sha256-${{ env.PKG_VERSION }}.txt, + apps/cli/bw-windows-${{ env.PKG_VERSION }}.zip, + apps/cli/bw-windows-sha256-${{ env.PKG_VERSION }}.txt, apps/cli/bw-oss-macos-${{ env.PKG_VERSION }}.zip, apps/cli/bw-oss-macos-sha256-${{ env.PKG_VERSION }}.txt, - apps/cli/bw-bit-macos-${{ env.PKG_VERSION }}.zip, - apps/cli/bw-bit-macos-sha256-${{ env.PKG_VERSION }}.txt, + apps/cli/bw-macos-${{ env.PKG_VERSION }}.zip, + apps/cli/bw-macos-sha256-${{ env.PKG_VERSION }}.txt, apps/cli/bw-oss-linux-${{ env.PKG_VERSION }}.zip, apps/cli/bw-oss-linux-sha256-${{ env.PKG_VERSION }}.txt, - apps/cli/bw-bit-linux-${{ env.PKG_VERSION }}.zip, - apps/cli/bw-bit-linux-sha256-${{ env.PKG_VERSION }}.txt, + apps/cli/bw-linux-${{ env.PKG_VERSION }}.zip, + apps/cli/bw-linux-sha256-${{ env.PKG_VERSION }}.txt, apps/cli/bitwarden-cli.${{ env.PKG_VERSION }}.nupkg, apps/cli/bw_${{ env.PKG_VERSION }}_amd64.snap, apps/cli/bw-snap-sha256-${{ env.PKG_VERSION }}.txt" From c01f6be28659491b28b4257c14063511eb00e766 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 27 Jun 2024 19:14:21 +0200 Subject: [PATCH 026/130] [PM-1802] Update 2fa provider icons and description (#9568) * Update yubikey to yubico * Update icons and descriptions * Change order of 2fa providers * Refactor 2fa providers into separate component * Update i18n messages for 2fa providers * Update design * Fix link * Remove unused SVGs * Undo changes to scss * Add speedbumps to links * Fix missing i18n string * Add a11y tags * Fix incorrect filepath * Remove unused i18n strings * Delete accidentally committed file * Fix premium and enabled checkmark being in new line * Rename two-factor-icon selector * Update authenticator names in two-factor-authenticator setup component * Update text according to figma design * Update keys to notify crowdin translators of changed content * Move svg icons to separate file * Fix incorrect i18n key --- apps/browser/src/_locales/en/messages.json | 18 +- apps/cli/src/locales/en/messages.json | 4 +- apps/desktop/src/locales/en/messages.json | 18 +- .../two-factor-authenticator.component.html | 73 +++-- .../two-factor-authenticator.component.ts | 25 ++ .../settings/two-factor-setup.component.html | 9 +- .../two-factor-yubikey.component.html | 2 +- .../auth/two-factor-options.component.html | 8 +- .../src/images/download_apple_appstore.svg | 46 +++ .../src/images/download_google_playstore.svg | 275 ++++++++++++++++++ apps/web/src/locales/en/messages.json | 71 +++-- apps/web/src/scss/plugins.scss | 18 +- .../components/two-factor-icon.component.html | 16 + .../components/two-factor-icon.component.ts | 24 ++ libs/angular/src/auth/icons/email.icon.ts | 44 +++ libs/angular/src/auth/icons/recovery.icon.ts | 51 ++++ libs/angular/src/auth/icons/totp.icon.ts | 61 ++++ libs/angular/src/auth/icons/webauthn.icon.ts | 42 +++ libs/angular/src/jslib.module.ts | 5 + .../src/auth/services/two-factor.service.ts | 20 +- 20 files changed, 728 insertions(+), 102 deletions(-) create mode 100755 apps/web/src/images/download_apple_appstore.svg create mode 100644 apps/web/src/images/download_google_playstore.svg create mode 100644 libs/angular/src/auth/components/two-factor-icon.component.html create mode 100644 libs/angular/src/auth/components/two-factor-icon.component.ts create mode 100644 libs/angular/src/auth/icons/email.icon.ts create mode 100644 libs/angular/src/auth/icons/recovery.icon.ts create mode 100644 libs/angular/src/auth/icons/totp.icon.ts create mode 100644 libs/angular/src/auth/icons/webauthn.icon.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 2675e38ee8c..0e8ffb1151d 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" diff --git a/apps/cli/src/locales/en/messages.json b/apps/cli/src/locales/en/messages.json index 3f753781127..f8a49c6e923 100644 --- a/apps/cli/src/locales/en/messages.json +++ b/apps/cli/src/locales/en/messages.json @@ -5,8 +5,8 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "emailTitle": { "message": "Email" diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 333a1c0e7bc..4781042413d 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html index 4e447bd8921..e796fd39a8e 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html @@ -5,13 +5,6 @@ {{ "authenticatorAppTitle" | i18n }} - - Authenticator app logo -

{{ "twoStepAuthenticatorDesc" | i18n }}

-

- 1. {{ "twoStepAuthenticatorDownloadApp" | i18n }} -

-

{{ "twoStepLoginProviderEnabled" | i18n }}

@@ -20,42 +13,64 @@ Authenticator app logo

{{ "twoStepAuthenticatorNeedApp" | i18n }}

-
    -
  • - {{ "iosDevices" | i18n }}: + +

    + {{ "twoStepAuthenticatorInstructionPrefix" | i18n }} AuthyAegis -

  • -
  • - {{ "androidDevices" | i18n }}: + {{ "twoStepAuthenticatorInstructionInfix1" | i18n }} Authy2FAS -
  • -
  • - {{ "windowsDevices" | i18n }}: + {{ "twoStepAuthenticatorInstructionInfix2" | i18n }} Microsoft AuthenticatorBitwarden Authenticator -
  • -
-

{{ "twoStepAuthenticatorAppsRecommended" | i18n }}

-

- 2. {{ "twoStepAuthenticatorScanCode" | i18n }} -

+ {{ "twoStepAuthenticatorInstructionSuffix" | i18n }} +

+ +

+ + Download on App Store + + + + + Get it on Google Play + +

+ {{ "twoStepAuthenticatorScanCodeV2" | i18n }} +


@@ -63,7 +78,7 @@

- 3. {{ "twoStepAuthenticatorEnterCode" | i18n }} + {{ "twoStepAuthenticatorEnterCodeV2" | i18n }} diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts index 17cdbb595f7..0a53f0f3c6a 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts @@ -148,4 +148,29 @@ export class TwoFactorAuthenticatorComponent ) { return dialogService.open(TwoFactorAuthenticatorComponent, config); } + + async launchExternalUrl(url: string) { + const hostname = new URL(url).hostname; + const confirmed = await this.dialogService.openSimpleDialog({ + title: this.i18nService.t("continueToExternalUrlTitle", hostname), + content: this.i18nService.t("continueToExternalUrlDesc"), + type: "info", + acceptButtonText: { key: "continue" }, + }); + if (confirmed) { + this.platformUtilsService.launchUri(url); + } + } + + async launchBitwardenUrl(url: string) { + const confirmed = await this.dialogService.openSimpleDialog({ + title: this.i18nService.t("twoStepContinueToBitwardenUrlTitle"), + content: this.i18nService.t("twoStepContinueToBitwardenUrlDesc"), + type: "info", + acceptButtonText: { key: "continue" }, + }); + if (confirmed) { + this.platformUtilsService.launchUri(url); + } + } } diff --git a/apps/web/src/app/auth/settings/two-factor-setup.component.html b/apps/web/src/app/auth/settings/two-factor-setup.component.html index 28baf72f885..33265e91f78 100644 --- a/apps/web/src/app/auth/settings/two-factor-setup.component.html +++ b/apps/web/src/app/auth/settings/two-factor-setup.component.html @@ -48,11 +48,16 @@
  • - +

    - {{ p.name }} +
    + {{ p.name }} +
    {{ "twoFactorYubikeySupportMobile" | i18n }}

- YubiKey OTP security key logo + Yubico OTP security key logo

{{ "twoFactorYubikeyAdd" | i18n }}:

  1. {{ "twoFactorYubikeyPlugIn" | i18n }}
  2. diff --git a/apps/web/src/app/auth/two-factor-options.component.html b/apps/web/src/app/auth/two-factor-options.component.html index e99c848a8d0..43c054060ea 100644 --- a/apps/web/src/app/auth/two-factor-options.component.html +++ b/apps/web/src/app/auth/two-factor-options.component.html @@ -5,8 +5,8 @@
    -
    - +
    +

    {{ p.name }}

    @@ -22,8 +22,8 @@
    -
    - rc logo +
    +

    {{ "recoveryCodeTitle" | i18n }}

    diff --git a/apps/web/src/images/download_apple_appstore.svg b/apps/web/src/images/download_apple_appstore.svg new file mode 100755 index 00000000000..072b425a1ab --- /dev/null +++ b/apps/web/src/images/download_apple_appstore.svg @@ -0,0 +1,46 @@ + + Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/images/download_google_playstore.svg b/apps/web/src/images/download_google_playstore.svg new file mode 100644 index 00000000000..35ee731b222 --- /dev/null +++ b/apps/web/src/images/download_google_playstore.svg @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 7a129f04e61..b0a638ad972 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." diff --git a/apps/web/src/scss/plugins.scss b/apps/web/src/scss/plugins.scss index 2f466484765..40ba692c463 100644 --- a/apps/web/src/scss/plugins.scss +++ b/apps/web/src/scss/plugins.scss @@ -32,29 +32,37 @@ .list-group-2fa { .logo-2fa { - min-width: 100px; + min-width: 120px; } } @each $mfaType in $mfaTypes { .mfaType#{$mfaType} { content: url("../images/two-factor/" + $mfaType + ".png"); - max-width: 100px; + max-width: 120px; + } +} + +.mfaType0 { + @include themify($themes) { + content: url("../images/two-factor/0.png"); + max-width: 120px; + max-height: 62px; } } .mfaType1 { @include themify($themes) { content: url("../images/two-factor/1" + themed("mfaLogoSuffix")); - max-width: 100px; - max-height: 45px; + max-width: 120px; + max-height: 62px; } } .mfaType7 { @include themify($themes) { content: url("../images/two-factor/7" + themed("mfaLogoSuffix")); - max-width: 100px; + max-width: 120px; } } diff --git a/libs/angular/src/auth/components/two-factor-icon.component.html b/libs/angular/src/auth/components/two-factor-icon.component.html new file mode 100644 index 00000000000..46d5211ca0a --- /dev/null +++ b/libs/angular/src/auth/components/two-factor-icon.component.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/libs/angular/src/auth/components/two-factor-icon.component.ts b/libs/angular/src/auth/components/two-factor-icon.component.ts new file mode 100644 index 00000000000..338ea25a3f3 --- /dev/null +++ b/libs/angular/src/auth/components/two-factor-icon.component.ts @@ -0,0 +1,24 @@ +import { Component, Input } from "@angular/core"; + +import { EmailIcon } from "../icons/email.icon"; +import { RecoveryCodeIcon } from "../icons/recovery.icon"; +import { TOTPIcon } from "../icons/totp.icon"; +import { WebAuthnIcon } from "../icons/webauthn.icon"; + +@Component({ + selector: "auth-two-factor-icon", + templateUrl: "./two-factor-icon.component.html", +}) +export class TwoFactorIconComponent { + @Input() provider: any; + @Input() name: string; + + protected readonly Icons = { + TOTPIcon, + EmailIcon, + WebAuthnIcon, + RecoveryCodeIcon, + }; + + constructor() {} +} diff --git a/libs/angular/src/auth/icons/email.icon.ts b/libs/angular/src/auth/icons/email.icon.ts new file mode 100644 index 00000000000..7b5163898fd --- /dev/null +++ b/libs/angular/src/auth/icons/email.icon.ts @@ -0,0 +1,44 @@ +import { svgIcon } from "@bitwarden/components"; + +export const EmailIcon = svgIcon` + + Email + + + + + + + + + + + + +`; diff --git a/libs/angular/src/auth/icons/recovery.icon.ts b/libs/angular/src/auth/icons/recovery.icon.ts new file mode 100644 index 00000000000..e23b46bebe1 --- /dev/null +++ b/libs/angular/src/auth/icons/recovery.icon.ts @@ -0,0 +1,51 @@ +import { svgIcon } from "@bitwarden/components"; + +export const RecoveryCodeIcon = svgIcon` + + Recovery Code + + + + + + + + + + + + +`; diff --git a/libs/angular/src/auth/icons/totp.icon.ts b/libs/angular/src/auth/icons/totp.icon.ts new file mode 100644 index 00000000000..1754e77b308 --- /dev/null +++ b/libs/angular/src/auth/icons/totp.icon.ts @@ -0,0 +1,61 @@ +import { svgIcon } from "@bitwarden/components"; + +export const TOTPIcon = svgIcon` + + TOTP Authenticator + + + + + + + + + + + + + + + + + +`; diff --git a/libs/angular/src/auth/icons/webauthn.icon.ts b/libs/angular/src/auth/icons/webauthn.icon.ts new file mode 100644 index 00000000000..a72692233d8 --- /dev/null +++ b/libs/angular/src/auth/icons/webauthn.icon.ts @@ -0,0 +1,42 @@ +import { svgIcon } from "@bitwarden/components"; + +export const WebAuthnIcon = svgIcon` + + Webauthn + + + + + + + + + + +`; diff --git a/libs/angular/src/jslib.module.ts b/libs/angular/src/jslib.module.ts index b03dde3a34a..f547799496e 100644 --- a/libs/angular/src/jslib.module.ts +++ b/libs/angular/src/jslib.module.ts @@ -17,6 +17,7 @@ import { DialogModule, FormFieldModule, IconButtonModule, + IconModule, LinkModule, MenuModule, RadioButtonModule, @@ -26,6 +27,7 @@ import { TypographyModule, } from "@bitwarden/components"; +import { TwoFactorIconComponent } from "./auth/components/two-factor-icon.component"; import { CalloutComponent } from "./components/callout.component"; import { A11yInvalidDirective } from "./directives/a11y-invalid.directive"; import { A11yTitleDirective } from "./directives/a11y-title.directive"; @@ -74,6 +76,7 @@ import { IconComponent } from "./vault/components/icon.component"; TableModule, MenuModule, IconButtonModule, + IconModule, LinkModule, ], declarations: [ @@ -109,6 +112,7 @@ import { IconComponent } from "./vault/components/icon.component"; ManageTaxInformationComponent, SelectPaymentMethodComponent, VerifyBankAccountComponent, + TwoFactorIconComponent, ], exports: [ A11yInvalidDirective, @@ -144,6 +148,7 @@ import { IconComponent } from "./vault/components/icon.component"; ManageTaxInformationComponent, SelectPaymentMethodComponent, VerifyBankAccountComponent, + TwoFactorIconComponent, ], providers: [ CreditCardNumberPipe, diff --git a/libs/common/src/auth/services/two-factor.service.ts b/libs/common/src/auth/services/two-factor.service.ts index 50d25561577..d67929c46f0 100644 --- a/libs/common/src/auth/services/two-factor.service.ts +++ b/libs/common/src/auth/services/two-factor.service.ts @@ -18,7 +18,7 @@ export const TwoFactorProviders: Partial Date: Thu, 27 Jun 2024 12:38:10 -0700 Subject: [PATCH 027/130] [PM-8938] two factor settings authenticator validation (#9857) * add validation * minor adjustments * better useability on submit button * removed img * fixed formatting --- .../two-factor-authenticator.component.html | 21 +++++++++++-------- .../two-factor-authenticator.component.ts | 14 ++++++++++--- .../settings/two-factor-base.component.ts | 1 + 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html index e796fd39a8e..f7ea36e02d4 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html @@ -10,7 +10,6 @@

    {{ "twoStepLoginProviderEnabled" | i18n }}

    {{ "twoStepAuthenticatorReaddDesc" | i18n }} - Authenticator app logo

    {{ "twoStepAuthenticatorNeedApp" | i18n }}

    @@ -72,19 +71,23 @@ {{ "twoStepAuthenticatorScanCodeV2" | i18n }}
    -

    +


    {{ key }}

    - - - {{ "twoStepAuthenticatorEnterCodeV2" | i18n }} - - - + + {{ "twoStepAuthenticatorEnterCodeV2" | 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 c137a51d72a..836d4cbbd1a 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 @@ -18,7 +18,7 @@ import { PasswordRepromptService } from "@bitwarden/vault"; import { BrowserApi } from "../../../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; -import { VaultPopupItemsService } from "../../../services/vault-popup-items.service"; +import { VaultPopupAutofillService } from "../../../services/vault-popup-autofill.service"; @Component({ standalone: true, @@ -39,16 +39,16 @@ export class ItemMoreOptionsComponent { @Input({ transform: booleanAttribute }) hideAutofillOptions: boolean; - protected autofillAllowed$ = this.vaultPopupItemsService.autofillAllowed$; + protected autofillAllowed$ = this.vaultPopupAutofillService.autofillAllowed$; constructor( private cipherService: CipherService, - private vaultPopupItemsService: VaultPopupItemsService, private passwordRepromptService: PasswordRepromptService, private toastService: ToastService, private dialogService: DialogService, private router: Router, private i18nService: I18nService, + private vaultPopupAutofillService: VaultPopupAutofillService, ) {} get canEdit() { @@ -62,10 +62,22 @@ export class ItemMoreOptionsComponent { return [CipherType.Login, CipherType.Card, CipherType.Identity].includes(this.cipher.type); } + get isLogin() { + return this.cipher.type === CipherType.Login; + } + get favoriteText() { return this.cipher.favorite ? "unfavorite" : "favorite"; } + async doAutofill() { + await this.vaultPopupAutofillService.doAutofill(this.cipher); + } + + async doAutofillAndSave() { + await this.vaultPopupAutofillService.doAutofillAndSave(this.cipher); + } + /** * Determines if the login cipher can be launched in a new browser tab. */ diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html index 90981204020..957747180eb 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html @@ -40,6 +40,7 @@ type="button" bitBadge variant="primary" + (click)="doAutofill(cipher)" [title]="'autofillTitle' | i18n: cipher.name" [attr.aria-label]="'autofillTitle' | i18n: cipher.name" > diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts index 0c810756352..b6ba09fb315 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts @@ -14,6 +14,7 @@ import { TypographyModule, } from "@bitwarden/components"; +import { VaultPopupAutofillService } from "../../../services/vault-popup-autofill.service"; import { PopupCipherView } from "../../../views/popup-cipher.view"; import { ItemCopyActionsComponent } from "../item-copy-action/item-copy-actions.component"; import { ItemMoreOptionsComponent } from "../item-more-options/item-more-options.component"; @@ -87,5 +88,12 @@ export class VaultListItemsContainerComponent { return cipher.collections[0]?.name; } - constructor(private i18nService: I18nService) {} + constructor( + private i18nService: I18nService, + private vaultPopupAutofillService: VaultPopupAutofillService, + ) {} + + async doAutofill(cipher: PopupCipherView) { + await this.vaultPopupAutofillService.doAutofill(cipher); + } } 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 9939727806b..14df62de12f 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 @@ -1,7 +1,7 @@ import { CommonModule } from "@angular/common"; import { Component, OnDestroy, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { Router, RouterLink } from "@angular/router"; +import { RouterLink } from "@angular/router"; import { combineLatest } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -59,10 +59,7 @@ export class VaultV2Component implements OnInit, OnDestroy { protected VaultStateEnum = VaultState; - constructor( - private vaultPopupItemsService: VaultPopupItemsService, - private router: Router, - ) { + constructor(private vaultPopupItemsService: VaultPopupItemsService) { combineLatest([ this.vaultPopupItemsService.emptyVault$, this.vaultPopupItemsService.noFilteredResults$, diff --git a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.spec.ts new file mode 100644 index 00000000000..6e74fd7c231 --- /dev/null +++ b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.spec.ts @@ -0,0 +1,356 @@ +import { TestBed } from "@angular/core/testing"; +import { mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; + +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { subscribeTo } from "@bitwarden/common/spec"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums"; +import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; +import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; +import { ToastService } from "@bitwarden/components"; +import { PasswordRepromptService } from "@bitwarden/vault"; + +import { + AutoFillOptions, + AutofillService, + PageDetail, +} from "../../../autofill/services/abstractions/autofill.service"; +import { BrowserApi } from "../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; + +import { VaultPopupAutofillService } from "./vault-popup-autofill.service"; + +describe("VaultPopupAutofillService", () => { + let testBed: TestBed; + let service: VaultPopupAutofillService; + + const mockCurrentTab = { url: "https://example.com" } as chrome.tabs.Tab; + + // Create mocks for VaultPopupAutofillService + const mockAutofillService = mock(); + const mockI18nService = mock(); + const mockToastService = mock(); + const mockPlatformUtilsService = mock(); + const mockPasswordRepromptService = mock(); + const mockCipherService = mock(); + const mockMessagingService = mock(); + + beforeEach(() => { + jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(false); + jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(mockCurrentTab); + + mockAutofillService.collectPageDetailsFromTab$.mockReturnValue(new BehaviorSubject([])); + + testBed = TestBed.configureTestingModule({ + providers: [ + { provide: AutofillService, useValue: mockAutofillService }, + { provide: I18nService, useValue: mockI18nService }, + { provide: ToastService, useValue: mockToastService }, + { provide: PlatformUtilsService, useValue: mockPlatformUtilsService }, + { provide: PasswordRepromptService, useValue: mockPasswordRepromptService }, + { provide: CipherService, useValue: mockCipherService }, + { provide: MessagingService, useValue: mockMessagingService }, + ], + }); + + service = testBed.inject(VaultPopupAutofillService); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it("should be created", () => { + expect(service).toBeTruthy(); + }); + + describe("currentAutofillTab$", () => { + it("should return null if in popout", (done) => { + jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(true); + service.refreshCurrentTab(); + service.currentAutofillTab$.subscribe((tab) => { + expect(tab).toBeNull(); + done(); + }); + }); + + it("should return BrowserApi.getTabFromCurrentWindow() if not in popout", (done) => { + service.currentAutofillTab$.subscribe((tab) => { + expect(tab).toEqual(mockCurrentTab); + expect(BrowserApi.getTabFromCurrentWindow).toHaveBeenCalled(); + done(); + }); + }); + + it("should only fetch the current tab once when subscribed to multiple times", async () => { + const firstTracked = subscribeTo(service.currentAutofillTab$); + const secondTracked = subscribeTo(service.currentAutofillTab$); + + await firstTracked.pauseUntilReceived(1); + await secondTracked.pauseUntilReceived(1); + + expect(BrowserApi.getTabFromCurrentWindow).toHaveBeenCalledTimes(1); + }); + }); + + describe("autofillAllowed$", () => { + it("should return true if there is a current tab", (done) => { + service.autofillAllowed$.subscribe((allowed) => { + expect(allowed).toBe(true); + done(); + }); + }); + + it("should return false if there is no current tab", (done) => { + jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(null); + service.refreshCurrentTab(); + service.autofillAllowed$.subscribe((allowed) => { + expect(allowed).toBe(false); + done(); + }); + }); + + it("should return false if in a popout", (done) => { + jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(true); + service.refreshCurrentTab(); + service.autofillAllowed$.subscribe((allowed) => { + expect(allowed).toBe(false); + done(); + }); + }); + }); + + describe("refreshCurrentTab()", () => { + it("should refresh currentAutofillTab$", async () => { + const tracked = subscribeTo(service.currentAutofillTab$); + service.refreshCurrentTab(); + await tracked.pauseUntilReceived(2); + }); + }); + + describe("autofill methods", () => { + const mockPageDetails: PageDetail[] = [{ tab: mockCurrentTab, details: {} as any, frameId: 1 }]; + let mockCipher: CipherView; + let expectedAutofillArgs: AutoFillOptions; + let mockPageDetails$: BehaviorSubject; + + beforeEach(() => { + mockCipher = new CipherView(); + mockCipher.type = CipherType.Login; + + mockPageDetails$ = new BehaviorSubject(mockPageDetails); + + mockAutofillService.collectPageDetailsFromTab$.mockReturnValue(mockPageDetails$); + + expectedAutofillArgs = { + tab: mockCurrentTab, + cipher: mockCipher, + pageDetails: mockPageDetails, + doc: expect.any(Document), + fillNewPassword: true, + allowTotpAutofill: true, + }; + + // Refresh the current tab so the mockedPageDetails$ are used + service.refreshCurrentTab(); + }); + + describe("doAutofill()", () => { + it("should return true if autofill is successful", async () => { + mockAutofillService.doAutoFill.mockResolvedValue(null); + const result = await service.doAutofill(mockCipher); + expect(result).toBe(true); + expect(mockAutofillService.doAutoFill).toHaveBeenCalledWith(expectedAutofillArgs); + }); + + it("should return false if autofill is not successful", async () => { + mockAutofillService.doAutoFill.mockRejectedValue(null); + const result = await service.doAutofill(mockCipher); + expect(result).toBe(false); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "error", + title: null, + message: mockI18nService.t("autofillError"), + }); + }); + + it("should return false if tab is null", async () => { + jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(null); + const result = await service.doAutofill(mockCipher); + expect(result).toBe(false); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "error", + title: null, + message: mockI18nService.t("autofillError"), + }); + }); + + it("should return false if missing page details", async () => { + mockPageDetails$.next([]); + const result = await service.doAutofill(mockCipher); + expect(result).toBe(false); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "error", + title: null, + message: mockI18nService.t("autofillError"), + }); + }); + + it("should show password prompt if cipher requires reprompt", async () => { + mockCipher.reprompt = CipherRepromptType.Password; + mockPasswordRepromptService.showPasswordPrompt.mockResolvedValue(false); + const result = await service.doAutofill(mockCipher); + expect(result).toBe(false); + }); + + it("should copy TOTP code to clipboard if available", async () => { + const totpCode = "123456"; + mockAutofillService.doAutoFill.mockResolvedValue(totpCode); + await service.doAutofill(mockCipher); + expect(mockPlatformUtilsService.copyToClipboard).toHaveBeenCalledWith( + totpCode, + expect.anything(), + ); + }); + + describe("closePopup", () => { + beforeEach(() => { + jest.spyOn(BrowserApi, "closePopup").mockImplementation(); + jest.spyOn(BrowserPopupUtils, "inPopup").mockReturnValue(true); + mockPlatformUtilsService.isFirefox.mockReturnValue(true); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it("should close popup by default when in popup", async () => { + await service.doAutofill(mockCipher); + expect(BrowserApi.closePopup).toHaveBeenCalled(); + }); + + it("should not close popup when closePopup is set to false", async () => { + await service.doAutofill(mockCipher, false); + expect(BrowserApi.closePopup).not.toHaveBeenCalled(); + }); + + it("should close popup after a timeout for chromium browsers", async () => { + mockPlatformUtilsService.isFirefox.mockReturnValue(false); + jest.spyOn(global, "setTimeout"); + await service.doAutofill(mockCipher); + jest.advanceTimersByTime(50); + expect(setTimeout).toHaveBeenCalledTimes(1); + expect(BrowserApi.closePopup).toHaveBeenCalled(); + }); + }); + }); + + describe("doAutofillAndSave()", () => { + beforeEach(() => { + // Mocks for service._closePopup() + jest.spyOn(BrowserApi, "closePopup").mockImplementation(); + jest.spyOn(BrowserPopupUtils, "inPopup").mockReturnValue(true); + mockPlatformUtilsService.isFirefox.mockReturnValue(true); + + // Default to happy path + mockAutofillService.doAutoFill.mockResolvedValue(null); + mockCipherService.updateWithServer.mockResolvedValue(null); + }); + + it("should return false if cipher is not login type", async () => { + mockCipher.type = CipherType.Card; + const result = await service.doAutofillAndSave(mockCipher); + expect(result).toBe(false); + expect(mockAutofillService.doAutoFill).not.toHaveBeenCalled(); + }); + + it("should return false if autofill is not successful", async () => { + mockAutofillService.doAutoFill.mockRejectedValue(null); + const result = await service.doAutofillAndSave(mockCipher); + expect(result).toBe(false); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "error", + title: null, + message: mockI18nService.t("autofillError"), + }); + }); + + it("should return true if the cipher already has a URI for the tab", async () => { + mockCipher.login = new LoginView(); + mockCipher.login.uris = [{ uri: mockCurrentTab.url } as LoginUriView]; + const result = await service.doAutofillAndSave(mockCipher); + expect(result).toBe(true); + expect(BrowserApi.closePopup).toHaveBeenCalled(); + expect(mockCipherService.updateWithServer).not.toHaveBeenCalled(); + }); + + it("should show a success toast if closePopup is false and cipher already has URI for tab", async () => { + mockCipher.login = new LoginView(); + mockCipher.login.uris = [{ uri: mockCurrentTab.url } as LoginUriView]; + const result = await service.doAutofillAndSave(mockCipher, false); + expect(result).toBe(true); + expect(BrowserApi.closePopup).not.toHaveBeenCalled(); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "success", + title: null, + message: mockI18nService.t("autoFillSuccessAndSavedUri"), + }); + expect(mockCipherService.updateWithServer).not.toHaveBeenCalled(); + }); + + it("should add a URI to the cipher and save with the server", async () => { + const mockEncryptedCipher = {} as Cipher; + mockCipherService.encrypt.mockResolvedValue(mockEncryptedCipher); + const result = await service.doAutofillAndSave(mockCipher); + expect(result).toBe(true); + expect(mockCipher.login.uris).toHaveLength(1); + expect(mockCipher.login.uris[0].uri).toBe(mockCurrentTab.url); + expect(mockCipherService.encrypt).toHaveBeenCalledWith(mockCipher); + expect(mockCipherService.updateWithServer).toHaveBeenCalledWith(mockEncryptedCipher); + }); + + it("should add a URI to the cipher when there are no existing URIs", async () => { + mockCipher.login.uris = null; + const result = await service.doAutofillAndSave(mockCipher); + expect(result).toBe(true); + expect(mockCipher.login.uris).toHaveLength(1); + expect(mockCipher.login.uris[0].uri).toBe(mockCurrentTab.url); + }); + + it("should show an error toast if saving the cipher fails", async () => { + mockCipherService.updateWithServer.mockRejectedValue(null); + const result = await service.doAutofillAndSave(mockCipher); + expect(result).toBe(false); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "error", + title: null, + message: mockI18nService.t("unexpectedError"), + }); + }); + + it("should close the popup after saving the cipher", async () => { + const result = await service.doAutofillAndSave(mockCipher); + expect(result).toBe(true); + expect(BrowserApi.closePopup).toHaveBeenCalled(); + }); + + it("should show success toast after saving the cipher if closePop is false", async () => { + mockAutofillService.doAutoFill.mockResolvedValue(null); + const result = await service.doAutofillAndSave(mockCipher, false); + expect(result).toBe(true); + expect(BrowserApi.closePopup).not.toHaveBeenCalled(); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "success", + title: null, + message: mockI18nService.t("autoFillSuccessAndSavedUri"), + }); + }); + }); + }); +}); diff --git a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts new file mode 100644 index 00000000000..ca59ffd9979 --- /dev/null +++ b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts @@ -0,0 +1,237 @@ +import { Injectable } from "@angular/core"; +import { + firstValueFrom, + map, + Observable, + of, + shareReplay, + startWith, + Subject, + switchMap, +} from "rxjs"; + +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; +import { ToastService } from "@bitwarden/components"; +import { PasswordRepromptService } from "@bitwarden/vault"; + +import { + AutofillService, + PageDetail, +} from "../../../autofill/services/abstractions/autofill.service"; +import { BrowserApi } from "../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; + +@Injectable({ + providedIn: "root", +}) +export class VaultPopupAutofillService { + private _refreshCurrentTab$ = new Subject(); + + /** + * Observable that contains the current tab to be considered for autofill. If there is no current tab + * or the popup is in a popout window, this will be null. + */ + currentAutofillTab$: Observable = this._refreshCurrentTab$.pipe( + startWith(null), + switchMap(async () => { + if (BrowserPopupUtils.inPopout(window)) { + return null; + } + return await BrowserApi.getTabFromCurrentWindow(); + }), + shareReplay({ refCount: false, bufferSize: 1 }), + ); + + /** + * Observable that indicates whether autofill is allowed in the current context. + * Autofill is allowed when there is a current tab and the popup is not in a popout window. + */ + autofillAllowed$: Observable = this.currentAutofillTab$.pipe(map((tab) => !!tab)); + + private _currentPageDetails$: Observable = this.currentAutofillTab$.pipe( + switchMap((tab) => { + if (!tab) { + return of([]); + } + return this.autofillService.collectPageDetailsFromTab$(tab); + }), + shareReplay({ refCount: false, bufferSize: 1 }), + ); + + constructor( + private autofillService: AutofillService, + private i18nService: I18nService, + private toastService: ToastService, + private platformUtilService: PlatformUtilsService, + private passwordRepromptService: PasswordRepromptService, + private cipherService: CipherService, + private messagingService: MessagingService, + ) { + this._currentPageDetails$.subscribe(); + } + + private async _internalDoAutofill( + cipher: CipherView, + tab: chrome.tabs.Tab, + pageDetails: PageDetail[], + ): Promise { + if ( + cipher.reprompt !== CipherRepromptType.None && + !(await this.passwordRepromptService.showPasswordPrompt()) + ) { + return false; + } + + if (tab == null || pageDetails.length === 0) { + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("autofillError"), + }); + return false; + } + + try { + const totpCode = await this.autofillService.doAutoFill({ + tab, + cipher, + pageDetails, + doc: window.document, + fillNewPassword: true, + allowTotpAutofill: true, + }); + + if (totpCode != null) { + this.platformUtilService.copyToClipboard(totpCode, { window: window }); + } + } catch { + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("autofillError"), + }); + return false; + } + + return true; + } + + private _closePopup() { + if (!BrowserPopupUtils.inPopup(window)) { + return; + } + + if (this.platformUtilService.isFirefox() || this.platformUtilService.isSafari()) { + BrowserApi.closePopup(window); + return; + } + + // Slight delay to fix bug in Chromium browsers where popup closes without copying totp to clipboard + setTimeout(() => BrowserApi.closePopup(window), 50); + } + + /** + * Re-fetch the current tab + */ + refreshCurrentTab() { + this._refreshCurrentTab$.next(null); + } + + /** + * Attempts to autofill the given cipher. Returns true if the autofill was successful, false otherwise. + * Will copy any TOTP code to the clipboard if available after successful autofill. + * @param cipher + * @param closePopup If true, will close the popup window after successful autofill. Defaults to true. + */ + async doAutofill(cipher: CipherView, closePopup = true): Promise { + const tab = await firstValueFrom(this.currentAutofillTab$); + const pageDetails = await firstValueFrom(this._currentPageDetails$); + + const didAutofill = await this._internalDoAutofill(cipher, tab, pageDetails); + + if (didAutofill && closePopup) { + this._closePopup(); + } + + return didAutofill; + } + + /** + * Attempts to autofill the given cipher and, upon successful autofill, saves the URI to the cipher. + * Will copy any TOTP code to the clipboard if available after successful autofill. + * @param cipher The cipher to autofill and save. Only Login ciphers are supported. + * @param closePopup If true, will close the popup window after successful autofill. + * If false, will show a success toast instead. Defaults to true. + */ + async doAutofillAndSave(cipher: CipherView, closePopup = true): Promise { + // We can only save URIs for login ciphers + if (cipher.type !== CipherType.Login) { + return false; + } + + const pageDetails = await firstValueFrom(this._currentPageDetails$); + const tab = await firstValueFrom(this.currentAutofillTab$); + + const didAutofill = await this._internalDoAutofill(cipher, tab, pageDetails); + + if (!didAutofill) { + return false; + } + + const didSaveUri = await this._saveNewUri(cipher, tab); + + if (!didSaveUri) { + return false; + } + + if (closePopup) { + this._closePopup(); + } else { + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("autoFillSuccessAndSavedUri"), + }); + } + + return true; + } + + /** + * Saves the current tab's URL as a new URI for the given cipher. If the cipher already has a URI for the tab, + * this method does nothing and returns true. + * @private + */ + private async _saveNewUri(cipher: CipherView, tab: chrome.tabs.Tab): Promise { + cipher.login.uris ??= []; + + if (cipher.login.uris.some((uri) => uri.uri === tab.url)) { + // Cipher already has a URI for this tab + return true; + } + + const loginUri = new LoginUriView(); + loginUri.uri = tab.url; + cipher.login.uris.push(loginUri); + + try { + const encCipher = await this.cipherService.encrypt(cipher); + await this.cipherService.updateWithServer(encCipher); + this.messagingService.send("editedCipher"); + return true; + } catch { + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("unexpectedError"), + }); + return false; + } + } +} 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 0b40b136ab9..e9abe7bff26 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 @@ -16,8 +16,8 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; import { BrowserApi } from "../../../platform/browser/browser-api"; -import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; +import { VaultPopupAutofillService } from "./vault-popup-autofill.service"; import { VaultPopupItemsService } from "./vault-popup-items.service"; import { VaultPopupListFiltersService } from "./vault-popup-list-filters.service"; @@ -36,6 +36,7 @@ describe("VaultPopupItemsService", () => { const vaultPopupListFiltersServiceMock = mock(); const searchService = mock(); const collectionService = mock(); + const vaultAutofillServiceMock = mock(); beforeEach(() => { allCiphers = cipherFactory(10); @@ -70,10 +71,10 @@ describe("VaultPopupItemsService", () => { vaultPopupListFiltersServiceMock.filterFunction$ = new BehaviorSubject( (ciphers: CipherView[]) => ciphers, ); - jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(false); - jest - .spyOn(BrowserApi, "getTabFromCurrentWindow") - .mockResolvedValue({ url: "https://example.com" } as chrome.tabs.Tab); + + vaultAutofillServiceMock.currentAutofillTab$ = new BehaviorSubject({ + url: "https://example.com", + } as chrome.tabs.Tab); mockOrg = { id: "org1", @@ -97,6 +98,7 @@ describe("VaultPopupItemsService", () => { { provide: OrganizationService, useValue: organizationServiceMock }, { provide: VaultPopupListFiltersService, useValue: vaultPopupListFiltersServiceMock }, { provide: CollectionService, useValue: collectionService }, + { provide: VaultPopupAutofillService, useValue: vaultAutofillServiceMock }, ], }); @@ -155,15 +157,7 @@ describe("VaultPopupItemsService", () => { describe("autoFillCiphers$", () => { it("should return empty array if there is no current tab", (done) => { - jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(null); - service.autoFillCiphers$.subscribe((ciphers) => { - expect(ciphers).toEqual([]); - done(); - }); - }); - - it("should return empty array if in Popout window", (done) => { - jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(true); + (vaultAutofillServiceMock.currentAutofillTab$ as BehaviorSubject).next(null); service.autoFillCiphers$.subscribe((ciphers) => { expect(ciphers).toEqual([]); done(); @@ -319,31 +313,6 @@ describe("VaultPopupItemsService", () => { }); }); - describe("autoFillAllowed$", () => { - it("should return true if there is a current tab", (done) => { - service.autofillAllowed$.subscribe((allowed) => { - expect(allowed).toBe(true); - done(); - }); - }); - - it("should return false if there is no current tab", (done) => { - jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(null); - service.autofillAllowed$.subscribe((allowed) => { - expect(allowed).toBe(false); - done(); - }); - }); - - it("should return false if in a Popout", (done) => { - jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(true); - service.autofillAllowed$.subscribe((allowed) => { - expect(allowed).toBe(false); - done(); - }); - }); - }); - describe("noFilteredResults$", () => { it("should return false when filteredResults has values", (done) => { service.noFilteredResults$.subscribe((noResults) => { 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 c6d155c5219..1c26f9cc712 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 @@ -28,11 +28,10 @@ import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { BrowserApi } from "../../../platform/browser/browser-api"; import { runInsideAngular } from "../../../platform/browser/run-inside-angular.operator"; -import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; import { PopupCipherView } from "../views/popup-cipher.view"; +import { VaultPopupAutofillService } from "./vault-popup-autofill.service"; import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-filters.service"; /** @@ -42,7 +41,6 @@ import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-fi providedIn: "root", }) export class VaultPopupItemsService { - private _refreshCurrentTab$ = new Subject(); private _searchText$ = new BehaviorSubject(""); /** @@ -70,22 +68,6 @@ export class VaultPopupItemsService { }), ); - /** - * Observable that contains the current tab to be considered for autofill. If there is no current tab - * or the popup is in a popout window, this will be null. - * @private - */ - private _currentAutofillTab$: Observable = this._refreshCurrentTab$.pipe( - startWith(null), - switchMap(async () => { - if (BrowserPopupUtils.inPopout(window)) { - return null; - } - return await BrowserApi.getTabFromCurrentWindow(); - }), - shareReplay({ refCount: false, bufferSize: 1 }), - ); - /** * Observable that contains the list of all decrypted ciphers. * @private @@ -145,7 +127,7 @@ export class VaultPopupItemsService { autoFillCiphers$: Observable = combineLatest([ this._filteredCipherList$, this._otherAutoFillTypes$, - this._currentAutofillTab$, + this.vaultPopupAutofillService.currentAutofillTab$, ]).pipe( switchMap(([ciphers, otherTypes, tab]) => { if (!tab) { @@ -217,12 +199,6 @@ export class VaultPopupItemsService { }), ); - /** - * Observable that indicates whether autofill is allowed in the current context. - * Autofill is allowed when there is a current tab and the popup is not in a popout window. - */ - autofillAllowed$: Observable = this._currentAutofillTab$.pipe(map((tab) => !!tab)); - /** * Observable that indicates whether the user's vault is empty. */ @@ -257,15 +233,9 @@ export class VaultPopupItemsService { private organizationService: OrganizationService, private searchService: SearchService, private collectionService: CollectionService, + private vaultPopupAutofillService: VaultPopupAutofillService, ) {} - /** - * Re-fetch the current tab to trigger a re-evaluation of the autofill ciphers. - */ - refreshCurrentTab() { - this._refreshCurrentTab$.next(null); - } - applyFilter(newSearchText: string) { this._searchText$.next(newSearchText); } From 982031633cb6bdfe410c901888f3f6db6058d5e5 Mon Sep 17 00:00:00 2001 From: Opeyemi Date: Thu, 27 Jun 2024 23:20:57 +0100 Subject: [PATCH 029/130] add env protection and restriction to USDEV (#9584) * add env protection and restriction to USDEV --- .github/workflows/deploy-web.yml | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/.github/workflows/deploy-web.yml b/.github/workflows/deploy-web.yml index 1ff67671419..5aa92c4dd8a 100644 --- a/.github/workflows/deploy-web.yml +++ b/.github/workflows/deploy-web.yml @@ -119,6 +119,49 @@ jobs: # Set the sync utility to use for deployment to the environment (az-sync or azcopy) echo "sync-utility=azcopy" >> $GITHUB_OUTPUT + - name: Environment Protection + env: + BUILD_WEB_RUN_ID: ${{ inputs.build-web-run-id }} + GH_TOKEN: ${{ github.token }} + run: | + BRANCH_OR_TAG_LOWER="" + if [[ "$BUILD_WEB_RUN_ID" == "" ]]; then + BRANCH_OR_TAG_LOWER=$(echo ${{ inputs.branch-or-tag }} | awk '{print tolower($0)}') + else + BRANCH_OR_TAG_LOWER=$(gh api /repos/bitwarden/clients/actions/runs/$BUILD_WEB_RUN_ID/artifacts --jq '.artifacts[0].workflow_run.head_branch' | awk '{print tolower($0)}') + fi + + echo "Branch/Tag: $BRANCH_OR_TAG_LOWER" + + PROD_ENV_PATTERN='USPROD|EUPROD' + PROD_ALLOWED_TAGS_PATTERN='web-v[0-9]+\.[0-9]+\.[0-9]+' + + QA_ENV_PATTERN='USQA|EUQA' + QA_ALLOWED_TAGS_PATTERN='.*' + + DEV_ENV_PATTERN='USDEV' + DEV_ALLOWED_TAGS_PATTERN='main' + + if [[ \ + ${{ inputs.environment }} =~ \.*($PROD_ENV_PATTERN)\.* && \ + ! "$BRANCH_OR_TAG_LOWER" =~ ^($PROD_ALLOWED_TAGS_PATTERN).* \ + ]] || [[ \ + ${{ inputs.environment }} =~ \.*($QA_ENV_PATTERN)\.* && \ + ! "$BRANCH_OR_TAG_LOWER" =~ ^($QA_ALLOWED_TAGS_PATTERN).* \ + ]] || [[ \ + ${{ inputs.environment }} =~ \.*($DEV_ENV_PATTERN)\.* && \ + $BRANCH_OR_TAG_LOWER != $DEV_ALLOWED_TAGS_PATTERN \ + ]]; then + echo "!Deployment blocked!" + echo "Attempting to deploy a tag that is not allowed in ${{ inputs.environment }} environment" + echo + echo "Environment: ${{ inputs.environment }}" + echo "Tag: $BRANCH_OR_TAG_LOWER" + exit 1 + else + echo "The input Branch/Tag: '$BRANCH_OR_TAG_LOWER' is allowed to deploy on ${{ inputs.environment }} environment" + fi + approval: name: Approval for Deployment to ${{ needs.setup.outputs.environment-name }} needs: setup From 09c6995e10a1d1ca31aaa03e30769f1c790f5abd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:31:59 +0000 Subject: [PATCH 030/130] Autosync the updated translations (#9866) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/af/messages.json | 33 ++++---- apps/desktop/src/locales/ar/messages.json | 33 ++++---- apps/desktop/src/locales/az/messages.json | 49 +++++------ apps/desktop/src/locales/be/messages.json | 33 ++++---- apps/desktop/src/locales/bg/messages.json | 33 ++++---- apps/desktop/src/locales/bn/messages.json | 33 ++++---- apps/desktop/src/locales/bs/messages.json | 33 ++++---- apps/desktop/src/locales/ca/messages.json | 33 ++++---- apps/desktop/src/locales/cs/messages.json | 31 +++---- apps/desktop/src/locales/cy/messages.json | 33 ++++---- apps/desktop/src/locales/da/messages.json | 33 ++++---- apps/desktop/src/locales/de/messages.json | 35 ++++---- apps/desktop/src/locales/el/messages.json | 33 ++++---- apps/desktop/src/locales/en_GB/messages.json | 33 ++++---- apps/desktop/src/locales/en_IN/messages.json | 33 ++++---- apps/desktop/src/locales/eo/messages.json | 33 ++++---- apps/desktop/src/locales/es/messages.json | 33 ++++---- apps/desktop/src/locales/et/messages.json | 33 ++++---- apps/desktop/src/locales/eu/messages.json | 33 ++++---- apps/desktop/src/locales/fa/messages.json | 33 ++++---- apps/desktop/src/locales/fi/messages.json | 37 +++++---- apps/desktop/src/locales/fil/messages.json | 33 ++++---- apps/desktop/src/locales/fr/messages.json | 87 ++++++++++---------- apps/desktop/src/locales/gl/messages.json | 33 ++++---- apps/desktop/src/locales/he/messages.json | 33 ++++---- apps/desktop/src/locales/hi/messages.json | 33 ++++---- apps/desktop/src/locales/hr/messages.json | 33 ++++---- apps/desktop/src/locales/hu/messages.json | 33 ++++---- apps/desktop/src/locales/id/messages.json | 33 ++++---- apps/desktop/src/locales/it/messages.json | 33 ++++---- apps/desktop/src/locales/ja/messages.json | 33 ++++---- apps/desktop/src/locales/ka/messages.json | 33 ++++---- apps/desktop/src/locales/km/messages.json | 33 ++++---- apps/desktop/src/locales/kn/messages.json | 33 ++++---- apps/desktop/src/locales/ko/messages.json | 33 ++++---- apps/desktop/src/locales/lt/messages.json | 33 ++++---- apps/desktop/src/locales/lv/messages.json | 41 ++++----- apps/desktop/src/locales/me/messages.json | 33 ++++---- apps/desktop/src/locales/ml/messages.json | 33 ++++---- apps/desktop/src/locales/mr/messages.json | 33 ++++---- apps/desktop/src/locales/my/messages.json | 33 ++++---- apps/desktop/src/locales/nb/messages.json | 33 ++++---- apps/desktop/src/locales/ne/messages.json | 33 ++++---- apps/desktop/src/locales/nl/messages.json | 31 +++---- apps/desktop/src/locales/nn/messages.json | 33 ++++---- apps/desktop/src/locales/or/messages.json | 33 ++++---- apps/desktop/src/locales/pl/messages.json | 33 ++++---- apps/desktop/src/locales/pt_BR/messages.json | 33 ++++---- apps/desktop/src/locales/pt_PT/messages.json | 35 ++++---- apps/desktop/src/locales/ro/messages.json | 33 ++++---- apps/desktop/src/locales/ru/messages.json | 33 ++++---- apps/desktop/src/locales/si/messages.json | 33 ++++---- apps/desktop/src/locales/sk/messages.json | 33 ++++---- apps/desktop/src/locales/sl/messages.json | 33 ++++---- apps/desktop/src/locales/sr/messages.json | 33 ++++---- apps/desktop/src/locales/sv/messages.json | 33 ++++---- apps/desktop/src/locales/te/messages.json | 33 ++++---- apps/desktop/src/locales/th/messages.json | 33 ++++---- apps/desktop/src/locales/tr/messages.json | 33 ++++---- apps/desktop/src/locales/uk/messages.json | 33 ++++---- apps/desktop/src/locales/vi/messages.json | 33 ++++---- apps/desktop/src/locales/zh_CN/messages.json | 43 +++++----- apps/desktop/src/locales/zh_TW/messages.json | 33 ++++---- 63 files changed, 1180 insertions(+), 991 deletions(-) diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index fdb978c8438..3e643925e7a 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Hoofwagwoordbevestiging stem nie ooreen nie." - }, - "newAccountCreated": { - "message": "U nuwe rekening is geskep! U kan nou aanteken." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Hoofwagwoordbevestiging stem nie ooreen nie." + }, + "newAccountCreated": { + "message": "U nuwe rekening is geskep! U kan nou aanteken." + }, "masterPassSent": { "message": "Ons het ’n e-pos gestuur met u hoofwagwoordwenk." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Waarmerktoep" }, - "authenticatorAppDesc": { - "message": "Gebruik ’n waarmerktoep (soos Authy of Google Authenticator) om tydgebaseerde bevestigingskodes optewek.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey-OTP-beveiligingsleutel" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Gebruik ’n YubiKey vir toegang tot u rekening. Werk met YubiKey 4, 4 Nano, 4C en NEO-toestelle." }, - "duoDesc": { - "message": "Bevestig met Duo Security d.m.v. die Duo Mobile-toep, SMS, spraakoproep of ’n U2F-beveiligingsleutel.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-pos" }, - "emailDesc": { - "message": "U sal bevestigingskodes per e-pos ontvang." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Aantekening onbeskikbaar" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index 22e1f984fd5..b80ec1b4dc9 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "لا يتطابق تأكيد كلمة المرور مع كلمة المرور." - }, - "newAccountCreated": { - "message": "تم إنشاء حسابك الجديد! يمكنك الآن تسجيل الدخول." - }, "youSuccessfullyLoggedIn": { "message": "سجلتَ الدخول بنجاح" }, "youMayCloseThisWindow": { "message": "يمكنك إغلاق هذه النافذة" }, + "masterPassDoesntMatch": { + "message": "لا يتطابق تأكيد كلمة المرور مع كلمة المرور." + }, + "newAccountCreated": { + "message": "تم إنشاء حسابك الجديد! يمكنك الآن تسجيل الدخول." + }, "masterPassSent": { "message": "لقد أرسلنا لك رسالة بريد إلكتروني تحتوي على تلميحات كلمة المرور الرئيسية." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "تطبيق المصادقة" }, - "authenticatorAppDesc": { - "message": "استخدام تطبيق مصادقة (مثل Authy أو Google Authenticator) لإنشاء رموز تحقق مستندة إلى الوقت.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "مفتاح أمان YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "استخدم YubiKey للوصول إلى حسابك. يعمل مع YubiKey 4 ،4 Nano ،4C، وأجهزة NEO." }, - "duoDesc": { - "message": "التحقق باستخدام نظام الحماية الثنائي باستخدام تطبيق Duo Mobile أو الرسائل القصيرة أو المكالمة الهاتفية أو مفتاح الأمان U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "البريد الإلكتروني" }, - "emailDesc": { - "message": "سيتم إرسال رمز التحقق إليك بالبريد الإلكتروني." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "تسجيل الدخول غير متاح" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "تأكيد كلمة مرور الملف" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "تم إلغاء المصادقة المتعددة" }, diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index acc8df982f3..2ef8ce0fc2c 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -113,7 +113,7 @@ "message": "Notlar" }, "customFields": { - "message": "Özəl sahələr" + "message": "Özəl xanalar" }, "launch": { "message": "Başlat" @@ -317,7 +317,7 @@ "message": "Qovluq" }, "newCustomField": { - "message": "Yeni özəl sahə" + "message": "Yeni özəl xana" }, "value": { "message": "Dəyər" @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Ana parolun təsdiqi uyuşmur." - }, - "newAccountCreated": { - "message": "Yeni hesabınız yaradıldı! İndi giriş edə bilərsiniz." - }, "youSuccessfullyLoggedIn": { "message": "Uğurla giriş etdiniz" }, "youMayCloseThisWindow": { "message": "Bu pəncərəni bağlaya bilərsiniz" }, + "masterPassDoesntMatch": { + "message": "Ana parolun təsdiqi uyuşmur." + }, + "newAccountCreated": { + "message": "Yeni hesabınız yaradıldı! İndi giriş edə bilərsiniz." + }, "masterPassSent": { "message": "Ana parol məsləhətini ehtiva edən bir e-poçt göndərdik." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Kimlik doğrulayıcı tətbiqi" }, - "authenticatorAppDesc": { - "message": "Vaxt əsaslı doğrulama kodları yaratmaq üçün (Authy və ya Google Authenticator kimi) kimlik doğrulayıcı tətbiq istifadə edin.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP güvənlik açarı" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Hesabınıza müraciət etmək üçün bir YubiKey istifadə edin. YubiKey 4, 4 Nano, 4C və NEO cihazları ilə işləyir." }, - "duoDesc": { - "message": "Duo Security ilə doğrulamaq üçün Duo Mobile tətbiqi, SMS, telefon zəngi və ya U2F güvənlik açarını istifadə edin.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-poçt" }, - "emailDesc": { - "message": "Doğrulama kodları e-poçt ünvanınıza göndəriləcək." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Giriş edilə bilmir" @@ -709,13 +709,13 @@ "message": "İki mərhələli giriş seçimləri" }, "selfHostedEnvironment": { - "message": "Öz-özünə sahiblik edən mühit" + "message": "Self-hosted mühit" }, "selfHostedEnvironmentFooter": { - "message": "Öz-özünə sahiblik edən Bitwarden quraşdırmasının baza URL-sini müəyyənləşdirin." + "message": "Öz-özünə sahiblik edən Bitwarden quraşdırmasının təməl URL-sini müəyyənləşdirin." }, "selfHostedBaseUrlHint": { - "message": "Şirkət daxili sahiblik edən Bitwarden quraşdırmasının təməl URL-sini qeyd edin. Nümunə: https://bitwarden.company.com" + "message": "Öz-özünə sahiblik edən Bitwarden quraşdırmasının təməl URL-sini müəyyənləşdirin. Nümunə: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { "message": "Qabaqcıl konfiqurasiya üçün hər xidmətin təməl URL-sini müstəqil olaraq qeyd edə bilərsiniz." @@ -2085,7 +2085,7 @@ "message": "Ana parol silindi." }, "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$, öz-özünə sahiblik edən açar serveri ilə SSO istifadə edir. Bu təşkilatın üzvlərinin giriş etməsi üçün artıq ana parol tələb edilməyəcək.", + "message": "$ORGANIZATION$, self-hosted açar serveri ilə SSO istifadə edir. Bu təşkilatın üzvlərinin giriş etməsi üçün artıq ana parol tələb edilməyəcək.", "placeholders": { "organization": { "content": "$1", @@ -2576,7 +2576,7 @@ "message": "Giriş edilir" }, "selfHostedServer": { - "message": "öz-özünə sahiblik edən" + "message": "self-hosted" }, "accessDenied": { "message": "Müraciət rədd edildi. Bu səhifəyə baxmaq üçün icazəniz yoxdur." @@ -2670,7 +2670,7 @@ "message": "Giriş, bir e-poçt ünvanı deyil." }, "fieldsNeedAttention": { - "message": "Yuxarıdakı $COUNT$ sahənin diqqətinizə ehtiyacı var.", + "message": "Yuxarıdakı $COUNT$ xananın diqqətinizə ehtiyacı var.", "placeholders": { "count": { "content": "$1", @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Fayl parolunu təsdiqlə" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Çox faktorlu kimlik doğrulama ləğv edildi" }, diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index c1095f8ee01..c1fa1119706 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Пацвярджэнне асноўнага пароля не супадае." - }, - "newAccountCreated": { - "message": "Ваш уліковы запіс створаны! Цяпер вы можаце ўвайсці ў яго." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Пацвярджэнне асноўнага пароля не супадае." + }, + "newAccountCreated": { + "message": "Ваш уліковы запіс створаны! Цяпер вы можаце ўвайсці ў яго." + }, "masterPassSent": { "message": "Мы адправілі вам на электронную пошту падказку да асноўнага пароля." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Праграма аўтэнтыфікацыі" }, - "authenticatorAppDesc": { - "message": "Выкарыстоўвайце праграму праграму аўтэнтыфікацыі (напрыклад, Authy або Google Authenticator) для генерацыі праверачных кодаў на падставе часу.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ бяспекі YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Выкарыстоўвайце YubiKey для доступу да вашага ўліковага запісу. Працуе з ключамі бяспекі YubiKey 4, 4 Nano, 4C і NEO." }, - "duoDesc": { - "message": "Праверка з дапамогай Duo Security, выкарыстоўваючы праграму Duo Mobile, SMS, тэлефонны выклік або ключ бяспекі U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Электронная пошта" }, - "emailDesc": { - "message": "Праверачныя коды будуць адпраўляцца вам па электронную пошту." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Уваход недаступны" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index 0832eee1f96..1128e96dd2f 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Главната парола и потвърждението ѝ не съвпадат." - }, - "newAccountCreated": { - "message": "Абонаментът ви бе създаден. Вече можете да се впишете." - }, "youSuccessfullyLoggedIn": { "message": "Вписахте се успешно" }, "youMayCloseThisWindow": { "message": "Може да затворите този прозорец" }, + "masterPassDoesntMatch": { + "message": "Главната парола и потвърждението ѝ не съвпадат." + }, + "newAccountCreated": { + "message": "Абонаментът ви бе създаден. Вече можете да се впишете." + }, "masterPassSent": { "message": "Изпратили сме ви е-писмо с подсказка за главната ви парола." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Приложение за удостоверяване" }, - "authenticatorAppDesc": { - "message": "Използвайте приложение за удостоверяване (като Authy или Google Authenticator) за генерирането на временни кодове за потвърждение.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Устройство YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Използвайте устройство на YubiKey, за да влезете в абонамента си. Поддържат се моделите YubiKey 4, 4 Nano, 4C и NEO." }, - "duoDesc": { - "message": "Удостоверяване чрез Duo Security, с ползване на приложението Duo Mobile, SMS, телефонен разговор или устройство U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Електронна поща" }, - "emailDesc": { - "message": "Кодовете за потвърждение ще ви бъдат пратени по е-поща." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Записът липсва" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Потвърждаване на паролата на файла" }, + "exportSuccess": { + "message": "Данните от трезора са изнесени" + }, "multifactorAuthenticationCancelled": { "message": "Многостъпковото удостоверяване е отменено" }, diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index 4957136e081..a383dd0a328 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "মূল পাসওয়ার্ড নিশ্চিতকরণ মেলেনি।" - }, - "newAccountCreated": { - "message": "আপনার নতুন অ্যাকাউন্ট তৈরি করা হয়েছে! আপনি এখন প্রবেশ করতে পারেন।" - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "মূল পাসওয়ার্ড নিশ্চিতকরণ মেলেনি।" + }, + "newAccountCreated": { + "message": "আপনার নতুন অ্যাকাউন্ট তৈরি করা হয়েছে! আপনি এখন প্রবেশ করতে পারেন।" + }, "masterPassSent": { "message": "আমরা আপনাকে আপনার মূল পাসওয়ার্ডের ইঙ্গিতসহ একটি ইমেল প্রেরণ করেছি।" }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "প্রমাণীকরণকারী অ্যাপ" }, - "authenticatorAppDesc": { - "message": "সময় ভিত্তিক যাচাইকরণ কোড উৎপন্ন করতে একটি প্রমাণীকরণকারী অ্যাপ্লিকেশন (যেমন Authy বা Google Authenticator) ব্যবহার করুন।", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP সুরক্ষা কী" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "আপনার অ্যাকাউন্ট ব্যাবহার করতে একটি YubiKey ব্যবহার করুন। YubiKey 4, 4 Nano, 4C, এবং NEO ডিভাইসগুলির সাথে কাজ করে।" }, - "duoDesc": { - "message": "Duo Mobile app, এসএমএস, ফোন কল, বা U2F সুরক্ষা কী ব্যবহার করে Duo Security এর মাধ্যমে যাচাই করুন।", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "ইমেইল" }, - "emailDesc": { - "message": "যাচাই কোডগুলি আপনাকে ই-মেইল করা হবে।" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "লগইন অনুপলব্ধ" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index d0d116499cf..a3e5c4dc2c4 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Potvrda glavne lozinke se ne podudara." - }, - "newAccountCreated": { - "message": "Tvoj novi račun je kreiran! Sada se možeš prijaviti." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Potvrda glavne lozinke se ne podudara." + }, + "newAccountCreated": { + "message": "Tvoj novi račun je kreiran! Sada se možeš prijaviti." + }, "masterPassSent": { "message": "Poslali smo vam e-mail sa podsjetnikom za glavnu lozinku." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplikacija za autentifikaciju" }, - "authenticatorAppDesc": { - "message": "Koristi aplikaciju za autentifikaciju (npr. Authy ili Google Authentifikator) za generiranje kontrolnih kodova.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP sigurnosni ključ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Koristi YubiKey za pristup svom računu. Radi s YubiKey 4, 4 Nano, 4C i NEO uređajima." }, - "duoDesc": { - "message": "Potvrdi sa Duo Security pomoću aplikacije Duo Mobile, SMS-om, telefonskim pozivom ili U2F sigurnosnim ključem.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-Mail " }, - "emailDesc": { - "message": "Verifikacijski kodovi će biti poslani E-Mailom." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Prijava nije moguća" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index 661ffa91801..41ab3bba0a4 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "La confirmació de la contrasenya mestra no coincideix." - }, - "newAccountCreated": { - "message": "El vostre compte s'ha creat correctament. Ara ja podeu iniciar sessió." - }, "youSuccessfullyLoggedIn": { "message": "Heu iniciat sessió correctament" }, "youMayCloseThisWindow": { "message": "Podeu tancar aquesta finestra" }, + "masterPassDoesntMatch": { + "message": "La confirmació de la contrasenya mestra no coincideix." + }, + "newAccountCreated": { + "message": "El vostre compte s'ha creat correctament. Ara ja podeu iniciar sessió." + }, "masterPassSent": { "message": "Hem enviat un correu electrònic amb la vostra contrasenya mestra." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplicació autenticadora" }, - "authenticatorAppDesc": { - "message": "Utilitzeu una aplicació autenticadora (com Authy o Google Authenticator) per generar codis de verificació basats en el temps.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Clau de seguretat OTP de YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utilitzeu una YubiKey per accedir al vostre compte. Funciona amb els dispositius YubiKey 4, 4 Nano, 4C i NEO." }, - "duoDesc": { - "message": "Verifiqueu amb Duo Security mitjançant l'aplicació Duo Mobile, SMS, trucada telefònica o clau de seguretat U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Correu electrònic" }, - "emailDesc": { - "message": "Els codis de verificació els rebreu per correu electrònic." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Inici de sessió no disponible" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirma la contrasenya del fitxer" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "S'ha cancel·lat l'autenticació multifactor" }, diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 285dd844c8d..dee3d75f694 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Potvrzení hlavního hesla se neshoduje." - }, - "newAccountCreated": { - "message": "Váš účet byl vytvořen! Můžete se přihlásit." - }, "youSuccessfullyLoggedIn": { "message": "Byli jste úspěšně přihlášeni" }, "youMayCloseThisWindow": { "message": "Toto okno můžete zavřít" }, + "masterPassDoesntMatch": { + "message": "Potvrzení hlavního hesla se neshoduje." + }, + "newAccountCreated": { + "message": "Váš účet byl vytvořen! Můžete se přihlásit." + }, "masterPassSent": { "message": "Poslali jsme vám e-mail s nápovědou k hlavnímu heslu." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Ověřovací aplikace" }, - "authenticatorAppDesc": { - "message": "Použijte ověřovací aplikaci (jako je Authy nebo Google Authenticator) pro generování časově omezených kódů.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Zadejte kód vygenerovaný ověřovací aplikací, jako je Autentikátor Bitwarden.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { + "yubiKeyTitleV2": { "message": "Bezpečnostní klíč YubiKey OTP" }, "yubiKeyDesc": { "message": "Použije YubiKey pro přístup k Vašemu trezoru. Podporuje YubiKey 4, 4 Nano, 4C a NEO." }, - "duoDesc": { - "message": "Ověření pomocí Duo Security prostřednictvím aplikace Duo Mobile, SMS, telefonního hovoru nebo bezpečnostního klíče U2F.", + "duoDescV2": { + "message": "Zadejte kód vygenerovaný DUO Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Ověřovací kódy Vám budou zaslány e-mailem." + "emailDescV2": { + "message": "Zadejte kód odeslaný na Váš e-mail." }, "loginUnavailable": { "message": "Přihlášení není dostupné" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Potvrzení hesla souboru" }, + "exportSuccess": { + "message": "Data trezoru byla exportována" + }, "multifactorAuthenticationCancelled": { "message": "Vícefázové ověření zrušeno" }, diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index 79cd680d0f9..94f20c3e300 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index 948e071fd99..bdb296ba717 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "De to adgangskoder matcher ikke." - }, - "newAccountCreated": { - "message": "Den nye konto er oprettet! Der kan nu logges ind." - }, "youSuccessfullyLoggedIn": { "message": "Du er nu logget ind" }, "youMayCloseThisWindow": { "message": "Dette vindue kan nu lukkes" }, + "masterPassDoesntMatch": { + "message": "De to adgangskoder matcher ikke." + }, + "newAccountCreated": { + "message": "Den nye konto er oprettet! Der kan nu logges ind." + }, "masterPassSent": { "message": "Der er sendt en e-mail til dig med dit hovedadgangskodetip." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Godkendelses-app" }, - "authenticatorAppDesc": { - "message": "Brug en godkendelses-app (såsom Authy eller Google Autenticator) til at generere tidsbaserede bekræftelseskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Angiv en kode genereret af en godkendelses-app såsom Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP-sikkerhedsnøgle" + "yubiKeyTitleV2": { + "message": "Yubico OTP-sikkerhedsnøgle" }, "yubiKeyDesc": { "message": "Brug en YubiKey for at tilgå din konto. Fungerer med YubiKey 4-, 4 Nano-, 4C- samt NEO-enheder." }, - "duoDesc": { - "message": "Bekræft med Duo Security vha. Duo Mobile-app, SMS, telefonopkald eller U2F-sikkerhedsnøgle.", + "duoDescV2": { + "message": "Angiv en kode genereret af Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Bekræftelseskoder vil blive e-mailet til dig." + "emailDescV2": { + "message": "Angiv en kode tilsendt pr. e-mail." }, "loginUnavailable": { "message": "Login utilgængelig" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Bekræft filadgangskode" }, + "exportSuccess": { + "message": "Boksdata eksporteret" + }, "multifactorAuthenticationCancelled": { "message": "Multifaktorgodkendelse afbrudt" }, diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 9491415a991..ffd018bcc72 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -500,7 +500,7 @@ "message": "Konto erstellen" }, "setAStrongPassword": { - "message": "Ein starkes Passwort festlegen" + "message": "Lege ein starkes Passwort fest" }, "finishCreatingYourAccountBySettingAPassword": { "message": "Schließe die Erstellung deines Kontos ab, indem du ein Passwort festlegst" @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Die Passwortbestätigung stimmt nicht mit dem Passwort überein." - }, - "newAccountCreated": { - "message": "Dein neues Konto wurde erstellt! Du kannst dich jetzt anmelden." - }, "youSuccessfullyLoggedIn": { "message": "Du hast dich erfolgreich angemeldet." }, "youMayCloseThisWindow": { "message": "Du kannst dieses Fenster schließen." }, + "masterPassDoesntMatch": { + "message": "Die Passwortbestätigung stimmt nicht mit dem Passwort überein." + }, + "newAccountCreated": { + "message": "Dein neues Konto wurde erstellt! Du kannst dich jetzt anmelden." + }, "masterPassSent": { "message": "Wir haben dir eine E-Mail mit dem Master-Passwort-Hinweis gesendet." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "authenticatorAppDesc": { - "message": "Verwende eine Authentifizierungs-App (wie zum Beispiel Authy oder Google Authenticator), um zeitbasierte Verifizierungscodes zu generieren.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey-OTP-Sicherheitsschlüssel" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Verwende einen YubiKey, um auf dein Konto zuzugreifen. Funktioniert mit den Geräten YubiKey 4, Nano 4, 4C und NEO." }, - "duoDesc": { - "message": "Verifiziere mit Duo Security, indem du die Duo-Mobile-App, SMS, Anrufe oder U2F-Sicherheitsschlüssel benutzt.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-Mail" }, - "emailDesc": { - "message": "Bestätigungscodes werden dir per E-Mail zugesandt." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Anmeldung nicht verfügbar" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Dateipasswort bestätigen" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifaktor-Authentifizierung abgebrochen" }, diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index 913fffddbc3..911a3735e6d 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Η επιβεβαίωση κύριου κωδικού δεν ταιριάζει." - }, - "newAccountCreated": { - "message": "Ο λογαριασμός σας έχει δημιουργηθεί! Τώρα μπορείτε να συνδεθείτε." - }, "youSuccessfullyLoggedIn": { "message": "Έχετε συνδεθεί επιτυχώς" }, "youMayCloseThisWindow": { "message": "Μπορείτε να κλείσετε αυτό το παράθυρο" }, + "masterPassDoesntMatch": { + "message": "Η επιβεβαίωση κύριου κωδικού δεν ταιριάζει." + }, + "newAccountCreated": { + "message": "Ο λογαριασμός σας έχει δημιουργηθεί! Τώρα μπορείτε να συνδεθείτε." + }, "masterPassSent": { "message": "Σας στείλαμε ένα email με την υπόδειξη του κύριου κωδικού." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Εφαρμογή Επαλήθευσης" }, - "authenticatorAppDesc": { - "message": "Χρησιμοποιήστε μια εφαρμογή επαλήθευσης (όπως το Authy ή Google Authenticator) για να δημιουργήσετε κωδικούς επαλήθευσης με βάση το χρόνο.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Κλειδί ασφαλείας YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Χρησιμοποιήστε ένα YubiKey για να αποκτήσετε πρόσβαση στο λογαριασμό σας. Λειτουργεί με συσκευές σειράς YubiKey 4, 4 Nano, 4C και συσκευές NEO." }, - "duoDesc": { - "message": "Επαληθεύστε με το Duo Security χρησιμοποιώντας την εφαρμογή Duo Mobile, SMS, τηλεφωνική κλήση ή κλειδί ασφαλείας U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Οι κωδικοί επαλήθευσης θα σας αποσταλούν μέσω ηλεκτρονικού ταχυδρομείου." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Σύνδεση μη διαθέσιμη" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Επιβεβαίωση κωδικού πρόσβασης αρχείου" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Ο πολυμερής έλεγχος ταυτότητας ακυρώθηκε" }, diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index 8bcba96311f..63d9cafd136 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index 47a65d56f60..6fa8989e863 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index edd3b61d4d8..cbea97186fd 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index 1c877b1c046..a0fc028f830 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "La confirmación de contraseña maestra no coincide." - }, - "newAccountCreated": { - "message": "¡Tu nueva cuenta ha sido creada! Ahora puedes acceder." - }, "youSuccessfullyLoggedIn": { "message": "Has iniciado sesión correctamente" }, "youMayCloseThisWindow": { "message": "Puedes cerrar esta ventana" }, + "masterPassDoesntMatch": { + "message": "La confirmación de contraseña maestra no coincide." + }, + "newAccountCreated": { + "message": "¡Tu nueva cuenta ha sido creada! Ahora puedes acceder." + }, "masterPassSent": { "message": "Te hemos enviado un correo electrónico con la pista de tu contraseña maestra." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplicación de autenticación" }, - "authenticatorAppDesc": { - "message": "Utiliza una aplicación de autenticación (como Authy o Google Authenticator) para generar código de verificación basados en tiempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Llave de seguridad YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Usa un Yubikey para acceder a tu cuenta. Funciona con YubiKey 4, 4 Nano, 4C y dispositivos NEO." }, - "duoDesc": { - "message": "Verificar con Duo Security usando la aplicación Duo Mobile, SMS, llamada telefónica o llave de seguridad U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Correo electrónico" }, - "emailDesc": { - "message": "Los códigos de verificación te serán enviados por correo electrónico." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Entrada no disponible" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirma la contraseña del archivo" }, + "exportSuccess": { + "message": "Datos de la caja fuerte exportados" + }, "multifactorAuthenticationCancelled": { "message": "Autenticación multifactor cancelada" }, diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index 43f3fc7731e..e799f8a2f40 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Ülemparoolid ei ühti." - }, - "newAccountCreated": { - "message": "Sinu konto on loodud! Võid nüüd sisse logida." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Ülemparoolid ei ühti." + }, + "newAccountCreated": { + "message": "Sinu konto on loodud! Võid nüüd sisse logida." + }, "masterPassSent": { "message": "Ülemparooli vihje saadeti Sinu e-postile." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Autentimise rakendus" }, - "authenticatorAppDesc": { - "message": "Kausta autentimise rakendust (näiteks Authy või Google Authenticator), et luua ajal baseeruvaid kinnituskoode.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Turvaline võti" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Kasuta kontole ligipääsemiseks YubiKey-d. See töötab YubiKey 4, 4 Nano, 4C ja NEO seadmetega." }, - "duoDesc": { - "message": "Kinnita Duo Security abil, kasutades selleks Duo Mobile rakendust, SMS-i, telefonikõnet või U2F turvavõtit.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Kinnituskoodid saadetakse e-postiga." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Sisselogimine ei ole saadaval" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index 608e81c03a3..e7347a53cf5 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Pasahitz nagusiaren egiaztatzea ez dator bat." - }, - "newAccountCreated": { - "message": "Zure kontua egina dago. Orain saioa has dezakezu." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Pasahitz nagusiaren egiaztatzea ez dator bat." + }, + "newAccountCreated": { + "message": "Zure kontua egina dago. Orain saioa has dezakezu." + }, "masterPassSent": { "message": "Mezu elektroniko bat bidali dizugu zure pasahitz nagusiaren pistarekin." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Autentifikazio aplikazioa" }, - "authenticatorAppDesc": { - "message": "Erabili autentifikazio aplikazio bat (adibidez, Authy edo Google Authenticator) denboran oinarritutako egiaztatze-kodeak sortzeko.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP segurtasun-gakoa" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Erabili YubiKey zure kontuan sartzeko. YubiKey 4, 4 Nano, 4C eta NEO gailuekin dabil." }, - "duoDesc": { - "message": "Egiaztatu Duo Securityrekin Duo Mobile aplikazioa, SMS, telefono deia edo U2F segurtasun-gakoa erabiliz.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Emaila" }, - "emailDesc": { - "message": "Egiaztatze-kodeak email bidez bidaliko dira." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Ez dago eskuragarri saio-hasierarik" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index 2f750dc9e61..aac7d569cb1 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "کلمه عبور اصلی با تکرار آن مطابقت ندارد." - }, - "newAccountCreated": { - "message": "حساب کاربری جدید شما ساخته شد! حالا می‌توانید وارد شوید." - }, "youSuccessfullyLoggedIn": { "message": "شما با موفقیت وارد شدید" }, "youMayCloseThisWindow": { "message": "می‌توانید این پنجره را ببندید" }, + "masterPassDoesntMatch": { + "message": "کلمه عبور اصلی با تکرار آن مطابقت ندارد." + }, + "newAccountCreated": { + "message": "حساب کاربری جدید شما ساخته شد! حالا می‌توانید وارد شوید." + }, "masterPassSent": { "message": "ما یک ایمیل همراه با یادآور کلمه عبور اصلی برایتان ارسال کردیم." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "برنامه احراز هویت" }, - "authenticatorAppDesc": { - "message": "از یک برنامه احراز هویت (مانند Authy یا Google Authenticator) استفاده کنید تا کدهای تأیید بر پایه زمان تولید کنید.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "کلید امنیتی YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "از یک YubiKey برای دسترسی به حسابتان استفاده کنید. همراه با دستگاه‌های YubiKey 4 ،4 Nano ،NEO کار می‌کند." }, - "duoDesc": { - "message": "با Duo Security با استفاده از برنامه تلفن همراه، پیامک، تماس تلفنی، یا کلید امنیتی U2F تأیید کنید.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "ایمیل" }, - "emailDesc": { - "message": "کد تأیید برایتان ارسال می‌شود." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "ورود به سیستم در دسترس نیست" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "تایید هویت چندمرحله‌ای کنسل شد" }, diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index f67aa2ab49d..46008a4447f 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -527,7 +527,7 @@ "message": "Pääsalasanan vihje (valinnainen)" }, "masterPassHintText": { - "message": "Jos unohdat salasanasi, salasanan vihje voidaan lähettää sähköpostiisi. Merkkien enimmäismäärä: $CURRENT$/$MAXIMUM$.", + "message": "Jos unohdat salasanasi, salasanavihje voidaan lähettää sähköpostiisi. Merkkien enimmäismäärä: $CURRENT$/$MAXIMUM$.", "placeholders": { "current": { "content": "$1", @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Pääsalasanan vahvistus ei täsmää." - }, - "newAccountCreated": { - "message": "Uusi käyttäjätilisi on luotu! Voit nyt kirjautua sisään." - }, "youSuccessfullyLoggedIn": { "message": "Kirjautuminen onnistui" }, "youMayCloseThisWindow": { "message": "Voit sulkea tämän ikkunan" }, + "masterPassDoesntMatch": { + "message": "Pääsalasanan vahvistus ei täsmää." + }, + "newAccountCreated": { + "message": "Uusi käyttäjätilisi on luotu! Voit nyt kirjautua sisään." + }, "masterPassSent": { "message": "Lähetimme pääsalasanasi vihjeen sinulle sähköpostitse." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Todennussovellus" }, - "authenticatorAppDesc": { - "message": "Käytä todennussovellusta (kuten Authy tai Google Authenticator) luodaksesi aikarajallisia todennuskoodeja.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP -todennuslaite" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Käytä YubiKey-todennuslaitetta tilisi avaukseen. Toimii YubiKey 4, 4 Nano, 4C sekä NEO -laitteiden kanssa." }, - "duoDesc": { - "message": "Vahvista Duo Securityn avulla käyttäen Duo Mobile ‑sovellusta, tekstiviestiä, puhelua tai U2F-todennuslaitetta.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Sähköposti" }, - "emailDesc": { - "message": "Todennuskoodit lähetetään sinulle sähköpostitse." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Kirjautuminen ei ole käytettävissä" @@ -2706,7 +2706,7 @@ "message": "Alavalikko" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Näytä/piilota sivuvalikko" }, "skipToContent": { "message": "Siirry sisältöön" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Vahvista tiedoston salasana" }, + "exportSuccess": { + "message": "Holvin tiedot on viety" + }, "multifactorAuthenticationCancelled": { "message": "Monivaiheinen todennus peruttiin" }, diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index 0f1f959e7fb..8eb371f8dcb 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Hindi tugma ang kumpirmasyon ng master password." - }, - "newAccountCreated": { - "message": "Nalikha na ang iyong bagong account! Maaari ka nang mag-log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Hindi tugma ang kumpirmasyon ng master password." + }, + "newAccountCreated": { + "message": "Nalikha na ang iyong bagong account! Maaari ka nang mag-log in." + }, "masterPassSent": { "message": "Pinadala na namin sa iyo ang email na may hint ng master password mo." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "App ng Authenticator" }, - "authenticatorAppDesc": { - "message": "Gumamit ng isang authenticator app (tulad ng Authy o Google Authenticator) upang makabuo ng mga code ng pag verify na batay sa oras.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP susi ng seguridad" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Gumamit ng YubiKey upang ma access ang iyong account. Gumagana sa YubiKey 4, 4 Nano, 4C, at NEO aparato." }, - "duoDesc": { - "message": "Patunayan sa Duo Security gamit ang Duo Mobile app, SMS, tawag sa telepono, o key ng seguridad ng U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Mag-email" }, - "emailDesc": { - "message": "Ang mga verification code ay i email sa iyo." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Hindi magagamit ang pag-login" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 9d13a216f23..817f200ce1f 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -527,7 +527,7 @@ "message": "Indice du mot de passe principal (facultatif)" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Si vous oubliez votre mot de passe, l'indice peut être envoyé à votre courriel. $CURRENT$/$MAXIMUM$ caractères maximum.", "placeholders": { "current": { "content": "$1", @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "La confirmation du mot de passe principal ne correspond pas." - }, - "newAccountCreated": { - "message": "Votre nouveau compte a été créé ! Vous pouvez maintenant vous authentifier." - }, "youSuccessfullyLoggedIn": { "message": "Vous vous êtes connecté avec succès" }, "youMayCloseThisWindow": { "message": "Vous pouvez fermer cette fenêtre" }, + "masterPassDoesntMatch": { + "message": "La confirmation du mot de passe principal ne correspond pas." + }, + "newAccountCreated": { + "message": "Votre nouveau compte a été créé ! Vous pouvez maintenant vous authentifier." + }, "masterPassSent": { "message": "Nous vous avons envoyé un courriel avec votre indice de mot de passe principal." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Application d'authentification" }, - "authenticatorAppDesc": { - "message": "Utiliser une application d'authentification (comme Authy ou Google Authenticator) pour générer des codes de vérification basés sur le temps.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Clé de sécurité YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utiliser une YubiKey pour accéder à votre compte. Fonctionne avec les appareils YubiKey 4, 4 Nano, 4C et NEO." }, - "duoDesc": { - "message": "S'authentifier avec Duo Security via l'application Duo Mobile, un SMS, un appel téléphonique, ou une clé de sécurité U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Courriel" }, - "emailDesc": { - "message": "Les codes de vérification vous seront envoyés par courriel." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Identifiant non disponible" @@ -1337,7 +1337,7 @@ "description": "ex. Date this password was updated" }, "exportFrom": { - "message": "Export from" + "message": "Exporter depuis" }, "exportVault": { "message": "Exporter le coffre" @@ -1364,13 +1364,13 @@ "message": "Définissez un mot de passe de fichier pour chiffrer l'export et déchiffrer son import sur n'importe quel compte Bitwarden." }, "exportTypeHeading": { - "message": "Export type" + "message": "Type d'exportation" }, "accountRestricted": { - "message": "Account restricted" + "message": "Compte restreint" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "Le \"Mot de passe du fichier\" et la \"Confirmation du mot de passe du fichier\" ne correspondent pas." }, "hCaptchaUrl": { "message": "URL hCaptcha", @@ -1679,19 +1679,19 @@ "message": "Votre nouveau mot de passe principal ne répond pas aux exigences de politique de sécurité." }, "receiveMarketingEmails": { - "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + "message": "Recevez des courriels de Bitwarden pour des annonces, des conseils et des opportunités de recherche." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Se désabonner" }, "atAnyTime": { - "message": "at any time." + "message": "à tout moment." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "En continuant, vous acceptez les" }, "and": { - "message": "and" + "message": "et" }, "acceptPolicies": { "message": "En cochant cette case vous acceptez ce qui suit :" @@ -2133,7 +2133,7 @@ "message": "Changer de compte" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "Vous avez déjà un compte ?" }, "options": { "message": "Options" @@ -2154,7 +2154,7 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "Export du coffre-fort de l'organisation" }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", @@ -2244,11 +2244,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Généré par Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Site web : $WEBSITE$. Généré par Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -2292,7 +2292,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Le domaine $SERVICENAME$ est invalide.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -2405,7 +2405,7 @@ "message": "Renvoyer la notification" }, "toggleCharacterCount": { - "message": "Activer/Désactiver le compte de caractères", + "message": "Activer / désactiver le compte de caractères", "description": "'Character count' describes a feature that displays a number next to each character of the password." }, "areYouTryingtoLogin": { @@ -2482,25 +2482,25 @@ "message": "Connexion demandée" }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Création du compte sur" }, "checkYourEmail": { - "message": "Check your email" + "message": "Vérifiez votre courriel" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Suivez le lien dans le courriel envoyé à" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "et continuer à créer votre compte." }, "noEmail": { - "message": "No email?" + "message": "Pas de courriel ?" }, "goBack": { - "message": "Go back" + "message": "Revenir en arrière" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "pour modifier votre courriel." }, "exposedMasterPassword": { "message": "Mot de passe principal exposé" @@ -2521,10 +2521,10 @@ "message": "Important :" }, "accessTokenUnableToBeDecrypted": { - "message": "You have been logged out because your access token could not be decrypted. Please log in again to resolve this issue." + "message": "Vous avez été déconnecté car votre jeton d'accès n'a pas pu être déchiffré. Veuillez vous reconnecter pour résoudre ce problème." }, "refreshTokenSecureStorageRetrievalFailure": { - "message": "You have been logged out because your refresh token could not be retrieved. Please log in again to resolve this issue." + "message": "Vous avez été déconnecté car votre jeton d'accès n'a pas pu être récupéré. Veuillez vous reconnecter pour résoudre ce problème." }, "masterPasswordHint": { "message": "Votre mot de passe principal ne peut pas être récupéré si vous l'oubliez !" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirmez le mot de passe du fichier" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Authentification multi-facteurs annulée" }, @@ -2965,11 +2968,11 @@ } }, "back": { - "message": "Back", + "message": "Retour", "description": "Button text to navigate back" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Supprimer $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index 767619b10f4..0887d769823 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index 1df2b148732..8d82180f1de 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "אימות סיסמה ראשית אינו תואם." - }, - "newAccountCreated": { - "message": "החשבון החדש שלך נוצר בהצלחה! כעת ניתן להתחבר למערכת." - }, "youSuccessfullyLoggedIn": { "message": "נכנסת בהצלחה" }, "youMayCloseThisWindow": { "message": "אפשר לסגור את החלון הזה" }, + "masterPassDoesntMatch": { + "message": "אימות סיסמה ראשית אינו תואם." + }, + "newAccountCreated": { + "message": "החשבון החדש שלך נוצר בהצלחה! כעת ניתן להתחבר למערכת." + }, "masterPassSent": { "message": "שלחנו לך אימייל עם רמז לסיסמה הראשית." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "אפליקציית אימות" }, - "authenticatorAppDesc": { - "message": "השתמש באפליקצית אימות (כמו לדוגמא Authy או Google Authenticator) לייצור סיסמאות אימות מבוססות זמן.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "מפתח אבטחה OTP של YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "השתמש בYubiKey עבור גישה לחשבון שלך. עובד עם YubiKey בגירסאות 4, 4C, 4Nano, ומכשירי NEO." }, - "duoDesc": { - "message": "בצע אימות מול Duo Security באמצעות אפליקצית Duo לפלאפון, SMS, שיחת טלפון, או מפתח אבטחה U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "אימייל" }, - "emailDesc": { - "message": "קודים לאימות יישלחו אליך באימייל." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "פרטי כניסה לא זמינים" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index 8a49a38899a..78367ecd0dd 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index c810085b128..6d26e9c3c6b 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Potvrda glavne lozinke se ne podudara." - }, - "newAccountCreated": { - "message": "Tvoj novi račun je kreiran! Sada se možeš prijaviti." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Potvrda glavne lozinke se ne podudara." + }, + "newAccountCreated": { + "message": "Tvoj novi račun je kreiran! Sada se možeš prijaviti." + }, "masterPassSent": { "message": "Poslali smo e-poštu s podsjetnikom glavne lozinke." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Autentifikatorska aplikacija" }, - "authenticatorAppDesc": { - "message": "Koristi autentifikatorsku aplikaciju (npr. Authy ili Google Authentifikator) za generiranje kontrolnih kodova.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP sigurnosni ključ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Koristi YubiKey za pristup svojem računu. Radi s YubiKey 4, 4 Nano, 4C i NEO uređajima." }, - "duoDesc": { - "message": "Potvrdi s Duo Security pomoću aplikacije Duo Mobile, SMS-om, telefonskim pozivom ili U2F sigurnosnim ključem.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-pošta" }, - "emailDesc": { - "message": "Verifikacijski kodovi će biti poslani e-poštom." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Prijava nije dostupna" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Potvrdi lozinku datoteke" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifaktorska autentifikacija otkazana" }, diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 957eba8a95e..14c97b81fe5 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "A mesterjelszó megerősítése nem egyezik." - }, - "newAccountCreated": { - "message": "A fiók létrehozásra került. Most már be lehet jelentkezni." - }, "youSuccessfullyLoggedIn": { "message": "A bejelentkezés sikeres volt." }, "youMayCloseThisWindow": { "message": "Most már bezárható ez az ablak." }, + "masterPassDoesntMatch": { + "message": "A mesterjelszó megerősítése nem egyezik." + }, + "newAccountCreated": { + "message": "A fiók létrehozásra került. Most már be lehet jelentkezni." + }, "masterPassSent": { "message": "Elküldtünk neked egy emailt a mesterjelszó emlékeztetővel." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Hitelesítő alkalmazás" }, - "authenticatorAppDesc": { - "message": "Hitelesítő alkalmazás használata (mint például az Authy vagy a Google Authenticator) idő alapú ellenőrzőkód generálásához.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Adjunk meg egy hitelesítő alkalmazás, például a Bitwarden Authenticator által generált kódot.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP egyszeri időalapú jelszó biztonsági kulcs" + "yubiKeyTitleV2": { + "message": "YubiKey OTP biztonsági kulcs" }, "yubiKeyDesc": { "message": "YubiKey használata a fiók eléréséhez. Működik a YubiKey 4, 4 Nano, 4C, és NEO eszközökkel." }, - "duoDesc": { - "message": "Ellenőrzés Duo Security segítségével a Duo Mobile alkalmazás, SMS, telefonhívás vagy U2F biztonsági kulcs használatával.", + "duoDescV2": { + "message": "Adjuk meg a Duo Security által generált kódot.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email cím" }, - "emailDesc": { - "message": "Az ellenőrző kódok emailben kerülnek elküldésre." + "emailDescV2": { + "message": "Adjuk meg az email címre elküldött kódot." }, "loginUnavailable": { "message": "A bejelentkezés nem érhető el." @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Fájl jelszó megerősítés" }, + "exportSuccess": { + "message": "A széfadatok exportálásra kerültek." + }, "multifactorAuthenticationCancelled": { "message": "A többtényezős hitelesítés megszakításra került." }, diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index f479704bf48..574ab5bb6b2 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Konfirmasi sandi utama tidak cocok." - }, - "newAccountCreated": { - "message": "Akun baru Anda telah dibuat! Sekarang Anda bisa masuk." - }, "youSuccessfullyLoggedIn": { "message": "Anda berhasil masuk" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Konfirmasi sandi utama tidak cocok." + }, + "newAccountCreated": { + "message": "Akun baru Anda telah dibuat! Sekarang Anda bisa masuk." + }, "masterPassSent": { "message": "Kami telah mengirimi Anda email dengan petunjuk sandi utama Anda." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplikasi Autentikasi" }, - "authenticatorAppDesc": { - "message": "Gunakan aplikasi autentikasi (seperti Authy atau Google Authenticator) untuk menghasilkan kode verifikasi berbasis waktu.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Kunci Keamanan OTP YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Gunakan YubiKey untuk mengakses akun Anda. Bekerja dengan YubiKey 4, 4 Nano, 4C, dan peranti NEO." }, - "duoDesc": { - "message": "Verifikasi dengan Duo Security menggunakan aplikasi Duo Mobile, SMS, panggilan telepon, atau kunci keamanan U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Kode verifikasi akan dikirim via email kepada Anda." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Info Masuk Tidak Tersedia" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index d7066a9e60f..c0c1e322c65 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Le password principali non corrispondono." - }, - "newAccountCreated": { - "message": "Il tuo nuovo account è stato creato! Ora puoi eseguire l'accesso." - }, "youSuccessfullyLoggedIn": { "message": "Hai effettuato l'accesso" }, "youMayCloseThisWindow": { "message": "Puoi chiudere questa finestra" }, + "masterPassDoesntMatch": { + "message": "Le password principali non corrispondono." + }, + "newAccountCreated": { + "message": "Il tuo nuovo account è stato creato! Ora puoi eseguire l'accesso." + }, "masterPassSent": { "message": "Ti abbiamo inviato un'email con il tuo suggerimento per la password principale." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "App di autenticazione" }, - "authenticatorAppDesc": { - "message": "Usa un'app di autenticazione (come Authy o Google Authenticator) per generare codici di verifica a tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chiave di sicurezza YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Usa YubiKey per accedere al tuo account. Compatibile con YubiKey 4, 4 Nano, 4C, e dispositivi NEO." }, - "duoDesc": { - "message": "Verifica con Duo Security usando l'app Duo Mobile, SMS, chiamata telefonica, o chiave di sicurezza U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "I codici di verifica ti saranno inviati per email." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login non disponibile" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Conferma password del file" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Verifica in due passaggi annullata" }, diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 96e23984e6b..4747d7f9762 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "マスターパスワードが一致しません。" - }, - "newAccountCreated": { - "message": "新しいアカウントを作成しました!今すぐログインできます。" - }, "youSuccessfullyLoggedIn": { "message": "ログインに成功しました" }, "youMayCloseThisWindow": { "message": "ウィンドウを閉じて大丈夫です" }, + "masterPassDoesntMatch": { + "message": "マスターパスワードが一致しません。" + }, + "newAccountCreated": { + "message": "新しいアカウントを作成しました!今すぐログインできます。" + }, "masterPassSent": { "message": "あなたのマスターパスワードのヒントを記載したメールを送信しました。" }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "認証アプリ" }, - "authenticatorAppDesc": { - "message": "Authy や Google 認証システムなどの認証アプリで時限式の認証コードを生成してください。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP セキュリティキー" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "YubiKey を使ってアカウントにアクセスできます。 YubiKey 4、4 Nano、4C、NEOに対応しています。" }, - "duoDesc": { - "message": "Duo Mobile アプリや SMS、電話や U2F セキュリティキーを使って Duo Security で認証します。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "メールアドレス" }, - "emailDesc": { - "message": "確認コードをメールにお送りします。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "ログインできません。" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "ファイルパスワードの確認" }, + "exportSuccess": { + "message": "保管庫データをエクスポートしました" + }, "multifactorAuthenticationCancelled": { "message": "多要素認証がキャンセルされました" }, diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 767619b10f4..0887d769823 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index 767619b10f4..0887d769823 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index 5f2b2411577..ae4d9150af5 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "ಮಾಸ್ಟರ್ ಪಾಸ್‌ವರ್ಡ್ ದೃಢೀಕರಣವು ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ." - }, - "newAccountCreated": { - "message": "ನಿಮ್ಮ ಹೊಸ ಖಾತೆಯನ್ನು ರಚಿಸಲಾಗಿದೆ! ನೀವು ಈಗ ಲಾಗ್ ಇನ್ ಮಾಡಬಹುದು." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "ಮಾಸ್ಟರ್ ಪಾಸ್‌ವರ್ಡ್ ದೃಢೀಕರಣವು ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ." + }, + "newAccountCreated": { + "message": "ನಿಮ್ಮ ಹೊಸ ಖಾತೆಯನ್ನು ರಚಿಸಲಾಗಿದೆ! ನೀವು ಈಗ ಲಾಗ್ ಇನ್ ಮಾಡಬಹುದು." + }, "masterPassSent": { "message": "ನಿಮ್ಮ ಮಾಸ್ಟರ್ ಪಾಸ್‌ವರ್ಡ್ ಸುಳಿವಿನೊಂದಿಗೆ ನಾವು ನಿಮಗೆ ಇಮೇಲ್ ಕಳುಹಿಸಿದ್ದೇವೆ." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್" }, - "authenticatorAppDesc": { - "message": "ಸಮಯ ಆಧಾರಿತ ಪರಿಶೀಲನಾ ಕೋಡ್‌ಗಳನ್ನು ರಚಿಸಲು ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸಿ (ಆಥಿ ಅಥವಾ ಗೂಗಲ್ ಅಥೆಂಟಿಕೇಟರ್).", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "ಯುಬಿಕೆ ಒಟಿಪಿ ಭದ್ರತಾ ಕೀ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "ನಿಮ್ಮ ಖಾತೆಯನ್ನು ಪ್ರವೇಶಿಸಲು ಯುಬಿಕೆ ಬಳಸಿ. ಯುಬಿಕೆ 4, 4 ನ್ಯಾನೋ, 4 ಸಿ ಮತ್ತು ಎನ್ಇಒ ಸಾಧನಗಳೊಂದಿಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ." }, - "duoDesc": { - "message": "ಡ್ಯುಯೊ ಮೊಬೈಲ್ ಅಪ್ಲಿಕೇಶನ್, ಎಸ್‌ಎಂಎಸ್, ಫೋನ್ ಕರೆ ಅಥವಾ ಯು 2 ಎಫ್ ಭದ್ರತಾ ಕೀಲಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಡ್ಯುಯೊ ಸೆಕ್ಯುರಿಟಿಯೊಂದಿಗೆ ಪರಿಶೀಲಿಸಿ.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "ಇಮೇಲ್" }, - "emailDesc": { - "message": "ಪರಿಶೀಲನೆ ಕೋಡ್‌ಗಳನ್ನು ನಿಮಗೆ ಇಮೇಲ್ ಮಾಡಲಾಗುತ್ತದೆ." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "ಲಾಗಿನ್ ಲಭ್ಯವಿಲ್ಲ" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 64ec0f45359..63d03f5ebf9 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "마스터 비밀번호 확인과 마스터 비밀번호가 일치하지 않습니다." - }, - "newAccountCreated": { - "message": "계정 생성이 완료되었습니다! 이제 로그인하실 수 있습니다." - }, "youSuccessfullyLoggedIn": { "message": "로그인에 성공했습니다." }, "youMayCloseThisWindow": { "message": "이제 창을 닫으실 수 있습니다." }, + "masterPassDoesntMatch": { + "message": "마스터 비밀번호 확인과 마스터 비밀번호가 일치하지 않습니다." + }, + "newAccountCreated": { + "message": "계정 생성이 완료되었습니다! 이제 로그인하실 수 있습니다." + }, "masterPassSent": { "message": "마스터 비밀번호 힌트가 담긴 이메일을 보냈습니다." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "인증 앱" }, - "authenticatorAppDesc": { - "message": "인증 앱(Authy, Google OTP 등)을 통하여 일회용 인증 코드를 생성합니다.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 보안 키" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "YubiKey를 사용하여 사용자의 계정에 접근합니다. YubiKey 4, 4 Nano, 4C 및 NEO 기기를 사용할 수 있습니다." }, - "duoDesc": { - "message": "Duo Mobile 앱, SMS, 전화 통화를 사용한 Duo Security 또는 U2F 보안 키를 사용하여 인증하세요.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "이메일" }, - "emailDesc": { - "message": "인증 코드가 담긴 이메일을 다시 보냅니다." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "로그인 불가능" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index b0b6405cedb..e1020f7d237 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Pagrindinio slaptažodžio patvirtinimas nesutampa." - }, - "newAccountCreated": { - "message": "Jūsų paskyra sukurta! Galite prisijungti." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Pagrindinio slaptažodžio patvirtinimas nesutampa." + }, + "newAccountCreated": { + "message": "Jūsų paskyra sukurta! Galite prisijungti." + }, "masterPassSent": { "message": "Išsiuntėme jums el. laišką su pagrindinio slaptažodžio užuomina." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Autentifikavimo programa" }, - "authenticatorAppDesc": { - "message": "Naudokite autentifikatoriaus programėlę (pvz. Authy arba Google Authenticator), kad sugeneruotumėte laiko patikrinimo kodus.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP saugumo raktas" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Naudokite YubiKey, kad prisijungtumėte prie savo paskyros. Veikia su YubiKey 4, 4 Nano, 4C ir NEO įrenginiais." }, - "duoDesc": { - "message": "Patvirtinkite su Duo Security naudodami Duo Mobile programą, SMS žinutę, telefono skambutį arba U2F saugumo raktą.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "El. paštas" }, - "emailDesc": { - "message": "Patvirtinimo kodai bus atsiųsti el. paštu." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Prisijungimas nepasiekiamas" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Patvirtinti failo slaptažodį" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Kelių veiksnių autentifikacija atšaukta" }, diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 6e0dcb30d4e..dfa25507de3 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -527,7 +527,7 @@ "message": "Galvenās paroles norāde (nav nepieciešama)" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Ja tiks aizmirsta parole, tās norādi var nosūtīt uz e-pasta adresi. $CURRENT$/$MAXIMUM$ lielākais pieļaujamais rakstzīmju skaits.", "placeholders": { "current": { "content": "$1", @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Galvenās paroles apstiprinājums nesakrīt." - }, - "newAccountCreated": { - "message": "Jaunais konts ir izveidots. Tagad vari pieteikties." - }, "youSuccessfullyLoggedIn": { "message": "Pieteikšanās bija veiksmīga" }, "youMayCloseThisWindow": { "message": "Šo logu var aizvērt" }, + "masterPassDoesntMatch": { + "message": "Galvenās paroles apstiprinājums nesakrīt." + }, + "newAccountCreated": { + "message": "Jaunais konts ir izveidots. Tagad vari pieteikties." + }, "masterPassSent": { "message": "Mēs nosūtījām galvenās paroles norādi e-pastā." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Autentificētāja lietotne" }, - "authenticatorAppDesc": { - "message": "Izmanto autentificētāja lietotni (piemēram, Authy vai Google autentifikators), lai izveidotu laikā balstītus apstiprinājuma kodus!", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP drošības atslēga" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Ir izmantojams YubiKey, lai piekļūtu savam kontam. Darbojas ar YubiKey 4, 4 Nano, 4C un NEO ierīcēm." }, - "duoDesc": { - "message": "Ar Duo Security apliecināšanu var veikt ar Duo Mobile lietotni, īsziņu, tālruņa zvanu vai U2F drošības atslēgu.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-pasts" }, - "emailDesc": { - "message": "Apstiprinājuma kodi tiks nosūtīti e-pastā." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Pieteikšanās nav pieejama" @@ -861,7 +861,7 @@ "message": "Sinhronizācija neizdevās" }, "yourVaultIsLocked": { - "message": "Glabātava ir aizslēgta. Jāapstiprina identitāte, lai turpinātu." + "message": "Glabātava ir aizslēgta. Jāapliecina sava identitāte, lai turpinātu." }, "unlock": { "message": "Atslēgt" @@ -1965,7 +1965,7 @@ "message": "Galvenās paroles apstiprināšana" }, "passwordConfirmationDesc": { - "message": "Šī darbība ir aizsargāta. Lai turpinātu, ir jāievada galvenā parole, lai apstiprinātu identitāti." + "message": "Šī darbība ir aizsargāta. Lai turpinātu, ir jāievada galvenā parole, lai apliecinātu savu identitāti." }, "updatedMasterPassword": { "message": "Galvenā parole atjaunināta" @@ -2706,7 +2706,7 @@ "message": "Apakšizvēlne" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Pārslēgt sānu pārvietošanās joslu" }, "skipToContent": { "message": "Pāriet uz saturu" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Apstiprināt datnes paroli" }, + "exportSuccess": { + "message": "Glabātavas saturs izgūts" + }, "multifactorAuthenticationCancelled": { "message": "Daudzpakāpju pieteikšanās atcelta" }, diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index fcfc3875a6a..6e02878b12d 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Potvrda glavne lozinke ne odgovara." - }, - "newAccountCreated": { - "message": "Vaš novi nalog je kreiran! Sada se možete prijaviti." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Potvrda glavne lozinke ne odgovara." + }, + "newAccountCreated": { + "message": "Vaš novi nalog je kreiran! Sada se možete prijaviti." + }, "masterPassSent": { "message": "Poslali smo vam email sa podsjetnikom na glavnu lozinku." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplikacija za autentifikaciju" }, - "authenticatorAppDesc": { - "message": "Koristi aplikaciju za autentifkaciju (kao što su Authy ili Google autentificator) da generišeš verfikacione kodove bazirane na vremenu.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP siguronosni ključ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Koristi YubiKey da pristupis svom nalogu. Radi sa YubiKey 4, 4 Nano, 4C i NEO uređajima." }, - "duoDesc": { - "message": "Potvrdite sa Duo Security, korišćenjem Duo Mobile aplikacije, SMS-a, telefonskog poziva ili U2F sigurnosnog ključa.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verifikacioni kodovi će vam biti poslati na email adresu." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Prijava nije dostupna" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index de4fd5ad8cb..880cc5b0848 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "പ്രാഥമിക പാസ്‌വേഡ് സ്ഥിരീകരണം പൊരുത്തപ്പെടുന്നില്ല." - }, - "newAccountCreated": { - "message": "തങ്ങളുടെ അക്കൗണ്ട് സൃഷ്ടിക്കപ്പെട്ടു. ഇനി താങ്കൾക്ക് ലോഗിൻ ചെയ്യാം." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "പ്രാഥമിക പാസ്‌വേഡ് സ്ഥിരീകരണം പൊരുത്തപ്പെടുന്നില്ല." + }, + "newAccountCreated": { + "message": "തങ്ങളുടെ അക്കൗണ്ട് സൃഷ്ടിക്കപ്പെട്ടു. ഇനി താങ്കൾക്ക് ലോഗിൻ ചെയ്യാം." + }, "masterPassSent": { "message": "നിങ്ങളുടെ പ്രാഥമിക പാസ്‌വേഡ് സൂചനയുള്ള ഒരു ഇമെയിൽ ഞങ്ങൾ നിങ്ങൾക്ക് അയച്ചു." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "ഓതന്റിക്കേറ്റർ ആപ്പ്" }, - "authenticatorAppDesc": { - "message": "സമയ-അടിസ്ഥാന പരിശോധന കോഡുകൾ സൃഷ്ടിക്കുന്നതിന് ഒരു ഓതന്റിക്കേറ്റർ അപ്ലിക്കേഷൻ (ഓത്തി അല്ലെങ്കിൽ Google ഓതന്റിക്കേറ്റർ പോലുള്ളവ) ഉപയോഗിക്കുക.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP സുരക്ഷാ കീ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "നിങ്ങളുടെ അക്കൗണ്ട് ആക്സസ് ചെയ്യുന്നതിന് ഒരു യൂബിക്കി ഉപയോഗിക്കുക. YubiKey 4, 4 Nano, 4C, NEO ഉപകരണങ്ങളിൽ പ്രവർത്തിക്കുന്നു." }, - "duoDesc": { - "message": "Duo Mobile അപ്ലിക്കേഷൻ, എസ്എംഎസ്, ഫോൺ കോൾ അല്ലെങ്കിൽ യു 2 എഫ് സുരക്ഷാ കീ ഉപയോഗിച്ച് Duoസെക്യൂരിറ്റി ഉപയോഗിച്ച് പരിശോധിക്കുക.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "ഇമെയിൽ" }, - "emailDesc": { - "message": "സ്ഥിരീകരണ കോഡുകൾ നിങ്ങൾക്ക് ഇമെയിൽ ചെയ്യും." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "പ്രവേശനം ലഭ്യമല്ല" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index 767619b10f4..0887d769823 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index ff0caa06d31..d007a4e0f45 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index de12803afe4..03d6c95a293 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Superpassord-bekreftelsen er ikke samsvarende." - }, - "newAccountCreated": { - "message": "Din nye konto har blitt opprettet! Du kan nå logge på." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Superpassord-bekreftelsen er ikke samsvarende." + }, + "newAccountCreated": { + "message": "Din nye konto har blitt opprettet! Du kan nå logge på." + }, "masterPassSent": { "message": "Vi har sendt deg en E-post med hintet til superpassordet." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Autentiseringsapp" }, - "authenticatorAppDesc": { - "message": "Bruk en autentiseringsapp (f․eks․ Authy eller Google Authenticator) for å generere tidsbegrensede verifiseringskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP-sikkerhetsnøkkel" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Bruk en YubiKey for å få tilgang til kontoen din. Virker med enheter av typene YubiKey 4, 4 Nano, 4C, og NEO." }, - "duoDesc": { - "message": "Verifiser med Duo Security gjennom Duo Mobile-appen, SMS, telefonsamtale, eller en U2F-sikkerhetsnøkkel.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Verifiseringskoder vil bli sendt til deg med E-post." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Innloggingen er utilgjengelig" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Bekreft filpassord" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifaktorautentisering ble avbrutt" }, diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index f7057c36ff2..560a5c41c70 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index a0661e3a4aa..796b23b0c36 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "De hoofdwachtwoorden komen niet overeen." - }, - "newAccountCreated": { - "message": "Je nieuwe account is aangemaakt! Je kunt nu inloggen." - }, "youSuccessfullyLoggedIn": { "message": "Je bent succesvol ingelogd" }, "youMayCloseThisWindow": { "message": "Je kunt dit venster sluiten" }, + "masterPassDoesntMatch": { + "message": "De hoofdwachtwoorden komen niet overeen." + }, + "newAccountCreated": { + "message": "Je nieuwe account is aangemaakt! Je kunt nu inloggen." + }, "masterPassSent": { "message": "We hebben je een e-mail gestuurd met je hoofdwachtwoordhint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticatie-app" }, - "authenticatorAppDesc": { - "message": "Gebruik een authenticatie-app (zoals Authy of Google Authenticator) om tijdgebaseerde authenticatiecodes te genereren.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Door een authenticatie-app zoals Bitwarden Authenticator gegenereerde code invoeren.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { + "yubiKeyTitleV2": { "message": "YubiKey OTP-beveiligingssleutel" }, "yubiKeyDesc": { "message": "Gebruik een YubiKey om toegang te krijgen tot je account. Werkt met YubiKey 4, 4 Nano, 4C en Neo-apparaten." }, - "duoDesc": { - "message": "Verificatie met Duo Security middels de Duo Mobile-app, sms, spraakoproep of een U2F-beveiligingssleutel.", + "duoDescV2": { + "message": "Door Duo Security gegenereerde code invoeren.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Je ontvangt verificatiecodes via e-mail." + "emailDescV2": { + "message": "Via e-mail verstuurde code invoeren." }, "loginUnavailable": { "message": "Login niet beschikbaar" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Bestandswachtwoord bevestigen" }, + "exportSuccess": { + "message": "Kluisgegevens geëxporteerd" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor-authenticatie geannuleerd" }, diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 4290e95103a..f6d4a6ed3c4 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Stadfesting av hovudpassordet samsvarar ikkje." - }, - "newAccountCreated": { - "message": "Den nye kontoen din har blitt oppretta! Du kan no logge inn." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Stadfesting av hovudpassordet samsvarar ikkje." + }, + "newAccountCreated": { + "message": "Den nye kontoen din har blitt oppretta! Du kan no logge inn." + }, "masterPassSent": { "message": "Me har sendt deg ein e-post med eit hint om hovudpassordet ditt." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Innlogginga er utilgjengeleg" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index bb84727af7d..d6781321446 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index c6888c1fb9d..ead83d7fa7c 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Hasła nie pasują do siebie." - }, - "newAccountCreated": { - "message": "Konto zostało utworzone! Teraz możesz się zalogować." - }, "youSuccessfullyLoggedIn": { "message": "Zalogowałeś się pomyślnie" }, "youMayCloseThisWindow": { "message": "Możesz zamknąć to okno" }, + "masterPassDoesntMatch": { + "message": "Hasła nie pasują do siebie." + }, + "newAccountCreated": { + "message": "Konto zostało utworzone! Teraz możesz się zalogować." + }, "masterPassSent": { "message": "Wysłaliśmy Tobie wiadomość e-mail z podpowiedzią do hasła głównego." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplikacja uwierzytelniająca" }, - "authenticatorAppDesc": { - "message": "Użyj aplikacji mobilnej (np. Authy lub Google Authenticator) do generowania czasowych kodów weryfikacyjnych.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Wprowadź kod wygenerowany przez aplikację uwierzytelniającą, jak Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Klucz bezpieczeństwa YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Klucz bezpieczeństwa Yubico OTP" }, "yubiKeyDesc": { "message": "Użyj YubiKey jako metody dostępu do konta. Działa z YubiKey 4, 4 Nano, 4C i urządzeniami NEO." }, - "duoDesc": { - "message": "Weryfikacja z użyciem Duo Security poprzez aplikację Duo Mobile, SMS, połączenie telefoniczne lub klucz bezpieczeństwa U2F.", + "duoDescV2": { + "message": "Wprowadź kod wygenerowany przez Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Adres e-mail" }, - "emailDesc": { - "message": "Kody weryfikacyjne zostaną wysłane do Ciebie wiadomością e-mail." + "emailDescV2": { + "message": "Wpisz kod wysłany na Twój adres e-mail." }, "loginUnavailable": { "message": "Logowanie jest niedostępne" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Potwierdź hasło pliku" }, + "exportSuccess": { + "message": "Dane sejfu zostały wyeksportowane" + }, "multifactorAuthenticationCancelled": { "message": "Uwierzytelnianie wieloskładnikowe zostało anulowane" }, diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index d5198c49aa4..de5ed3fc600 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "A confirmação da senha mestra não corresponde." - }, - "newAccountCreated": { - "message": "A sua nova conta foi criada! Agora você pode iniciar a sessão." - }, "youSuccessfullyLoggedIn": { "message": "Você logou na sua conta com sucesso" }, "youMayCloseThisWindow": { "message": "Você pode fechar esta janela" }, + "masterPassDoesntMatch": { + "message": "A confirmação da senha mestra não corresponde." + }, + "newAccountCreated": { + "message": "A sua nova conta foi criada! Agora você pode iniciar a sessão." + }, "masterPassSent": { "message": "Enviamos um e-mail com a dica da sua senha mestra." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplicativo de Autenticação" }, - "authenticatorAppDesc": { - "message": "Utilize um aplicativo de autenticação (tal como Authy ou Google Authenticator) para gerar códigos de verificação baseados no tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chave de Segurança YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utilize uma YubiKey para acessar a sua conta. Funciona com YubiKey 4, 4 Nano, 4C, e dispositivos NEO." }, - "duoDesc": { - "message": "Verifique com o Duo Security utilizando o aplicativo Duo Mobile, SMS, chamada telefônica, ou chave de segurança U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Os códigos de verificação vão ser enviados por e-mail para você." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Sessão Indisponível" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirmar senha do arquivo" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Autenticação de múltiplos fatores cancelada" }, diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index 4301627958c..79af98c25f6 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -266,7 +266,7 @@ "message": "Nome próprio" }, "middleName": { - "message": "Segundo nome" + "message": "Nome do meio" }, "lastName": { "message": "Apelido" @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "A confirmação da palavra-passe mestra não corresponde." - }, - "newAccountCreated": { - "message": "A sua nova conta foi criada! Pode agora iniciar sessão." - }, "youSuccessfullyLoggedIn": { "message": "Iniciou sessão com sucesso" }, "youMayCloseThisWindow": { "message": "Pode fechar esta janela" }, + "masterPassDoesntMatch": { + "message": "A confirmação da palavra-passe mestra não corresponde." + }, + "newAccountCreated": { + "message": "A sua nova conta foi criada! Pode agora iniciar sessão." + }, "masterPassSent": { "message": "Enviámos-lhe um e-mail com a dica da sua palavra-passe mestra." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplicação de autenticação" }, - "authenticatorAppDesc": { - "message": "Utilize uma aplicação de autenticação (como o Authy ou o Google Authenticator) para gerar códigos de verificação baseados no tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Introduza um código gerado por uma aplicação de autenticação como o Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chave de segurança YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Chave de segurança Yubico OTP" }, "yubiKeyDesc": { "message": "Utilize uma YubiKey para aceder à sua conta. Funciona com os dispositivos YubiKey 4, 4 Nano, 4C e NEO." }, - "duoDesc": { - "message": "Verifique com a Duo Security utilizando a aplicação Duo Mobile, SMS, chamada telefónica ou chave de segurança U2F.", + "duoDescV2": { + "message": "Introduza um código gerado pelo Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Os códigos de verificação ser-lhe-ão enviados por e-mail." + "emailDescV2": { + "message": "Introduza um código enviado para o seu e-mail." }, "loginUnavailable": { "message": "Início de sessão indisponível" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirmar a palavra-passe do ficheiro" }, + "exportSuccess": { + "message": "Dados do cofre exportados" + }, "multifactorAuthenticationCancelled": { "message": "Autenticação multifator cancelada" }, diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index 6d56b5f7d31..874240889ed 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Parola principală și confirmarea ei nu coincid!" - }, - "newAccountCreated": { - "message": "Noul dvs. cont a fost creat! Acum vă puteți autentifica." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Parola principală și confirmarea ei nu coincid!" + }, + "newAccountCreated": { + "message": "Noul dvs. cont a fost creat! Acum vă puteți autentifica." + }, "masterPassSent": { "message": "V-am trimis un e-mail cu indiciul parolei principale." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Aplicația Autentificator" }, - "authenticatorAppDesc": { - "message": "Utilizați o aplicație de autentificare (cum ar fi Authy sau Google Authenticator) pentru a genera codurile de verificare bazate pe timp.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Cheie de securitate YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utilizați un YubiKey pentru a vă accesa contul. Funcționează cu dispozitivele YubiKey 4, 4 Nano, 4C și NEO." }, - "duoDesc": { - "message": "Verificați cu Duo Security utilizând aplicația Duo Mobile, SMS, apel telefonic sau cheia de securitate U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Codurile de verificare vor fi trimise prin e-mail." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Autentificare indisponibilă" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index 780facaab26..9f406e56d90 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Мастер-пароли не совпадают." - }, - "newAccountCreated": { - "message": "Аккаунт создан! Теперь вы можете войти в систему." - }, "youSuccessfullyLoggedIn": { "message": "Вы успешно авторизовались" }, "youMayCloseThisWindow": { "message": "Можете закрыть это окно" }, + "masterPassDoesntMatch": { + "message": "Мастер-пароли не совпадают." + }, + "newAccountCreated": { + "message": "Аккаунт создан! Теперь вы можете войти в систему." + }, "masterPassSent": { "message": "Мы отправили вам письмо с подсказкой к мастер-паролю." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Приложение-аутентификатор" }, - "authenticatorAppDesc": { - "message": "Используйте приложение-аутентификатор (например Authy или Google Authenticator) для создания кодов проверки на основе времени.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ безопасности YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Используйте YubiKey для доступа к аккаунту. Работает с устройствами YubiKey серий 4, 5 и NEO." }, - "duoDesc": { - "message": "Подтвердите с помощью Duo Security, используя приложение Duo Mobile, SMS, телефонный звонок или ключ безопасности U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Коды подтверждения будут отправлены вам по электронной почте." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Вход недоступен" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Подтвердите пароль к файлу" }, + "exportSuccess": { + "message": "Данные хранилища экспортированы" + }, "multifactorAuthenticationCancelled": { "message": "Многофакторная аутентификация отменена" }, diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index 9b54752a16e..906181c7bdb 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "වි-තැපෑල" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index d45ebff7f5e..f38ca2033a4 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Potvrdenie hlavného hesla sa nezhoduje." - }, - "newAccountCreated": { - "message": "Váš nový účet bol vytvorený! Teraz sa môžete prihlásiť." - }, "youSuccessfullyLoggedIn": { "message": "Úspešne ste sa prihlásili" }, "youMayCloseThisWindow": { "message": "Toto okno môžete zavrieť" }, + "masterPassDoesntMatch": { + "message": "Potvrdenie hlavného hesla sa nezhoduje." + }, + "newAccountCreated": { + "message": "Váš nový účet bol vytvorený! Teraz sa môžete prihlásiť." + }, "masterPassSent": { "message": "Emailom sme vám poslali nápoveď k hlavnému heslu." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Overovacia aplikácia" }, - "authenticatorAppDesc": { - "message": "Použite overovaciu aplikáciu (napríklad Authy alebo Google Authenticator) na generovanie časovo obmedzených overovacích kódov.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Zadajte kód vygenerovaný overovacou aplikáciou akou je Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP bezpečnostný kľúč" + "yubiKeyTitleV2": { + "message": "Bezpečnostný kľúč Yubico OTP" }, "yubiKeyDesc": { "message": "Použiť YubiKey pre prístup k vášmu účtu. Pracuje s YubiKey 4, 4 Nano, 4C a s NEO zariadeniami." }, - "duoDesc": { - "message": "Overiť sa prostredníctvom Duo Security použitím Duo Mobile aplikácie, SMS, telefonátu alebo U2F bezpečnostným kľúčom.", + "duoDescV2": { + "message": "Zadajte kód vygenerovaný aplikáciou Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Overovacie kódy vám budú zaslané emailom." + "emailDescV2": { + "message": "Zadajte kód zaslaný na váš e-mail." }, "loginUnavailable": { "message": "Prihlásenie nedostupné" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Potvrdiť heslo súboru" }, + "exportSuccess": { + "message": "Údaje z trezora boli exportované" + }, "multifactorAuthenticationCancelled": { "message": "Viacfaktorové overenie zrušené" }, diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 7d3396e18d8..e275b396620 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Avtentikacijska aplikacija" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-pošta" }, - "emailDesc": { - "message": "Potrditvene kode vam bodo posredovane po e-pošti." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Prijava ni na voljo" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index ff8d0c32822..e254b694c34 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Потврђена Главна Лозинка се не подудара." - }, - "newAccountCreated": { - "message": "Ваш налог је креиран! Сада се можете пријавити." - }, "youSuccessfullyLoggedIn": { "message": "Успешно сте се пријавили" }, "youMayCloseThisWindow": { "message": "Можете затворити овај прозор" }, + "masterPassDoesntMatch": { + "message": "Потврђена Главна Лозинка се не подудара." + }, + "newAccountCreated": { + "message": "Ваш налог је креиран! Сада се можете пријавити." + }, "masterPassSent": { "message": "Послали смо Вам поруку са саветом главне лозинке." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Апликација Аутентификатор" }, - "authenticatorAppDesc": { - "message": "Користите апликацију за аутентификацију (као што је Authy или Google Authenticator) за генерисање верификационих кодова.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Унесите кôд који генерише апликација за аутентификацију као што је Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP сигурносни кључ" + "yubiKeyTitleV2": { + "message": "Yubico OTP сигурносни кључ" }, "yubiKeyDesc": { "message": "Користите YubiKey за приступ налогу. Ради са YubiKey 4, 4 Nano, 4C, и NEO уређајима." }, - "duoDesc": { - "message": "Провери са Duo Security користећи Duo Mobile апликацију, СМС, телефонски позив, или U2F кључ.", + "duoDescV2": { + "message": "Унесите кôд који је генерисао Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Имејл" }, - "emailDesc": { - "message": "Верификациони кодови ће вам бити послати имејлом." + "emailDescV2": { + "message": "Унесите кôд послат на ваш имејл." }, "loginUnavailable": { "message": "Пријава недоступна" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Потврдити лозинку датотеке" }, + "exportSuccess": { + "message": "Подаци из сефа су извезени" + }, "multifactorAuthenticationCancelled": { "message": "Вишефакторска аутентификација је отказана" }, diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index 252f077b019..3e73b2598b7 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Huvudlösenorden stämmer inte överens." - }, - "newAccountCreated": { - "message": "Ditt nya konto har skapats! Du kan nu logga in." - }, "youSuccessfullyLoggedIn": { "message": "Du är nu inloggad" }, "youMayCloseThisWindow": { "message": "Du kan stänga detta fönster" }, + "masterPassDoesntMatch": { + "message": "Huvudlösenorden stämmer inte överens." + }, + "newAccountCreated": { + "message": "Ditt nya konto har skapats! Du kan nu logga in." + }, "masterPassSent": { "message": "Vi har skickat ett e-postmeddelande till dig med din huvudlösenordsledtråd." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Autentiseringsapp" }, - "authenticatorAppDesc": { - "message": "Använd en autentiseringsapp (t.ex. Authy eller Google Authenticator) för att skapa tidsbaserade verifieringskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP-säkerhetsnyckel" + "yubiKeyTitleV2": { + "message": "Yubico OTP-säkerhetsnyckel" }, "yubiKeyDesc": { "message": "Använd en YubiKey för att komma åt ditt konto. Fungerar med YubiKey 4, 4 Nano, 4C och NEO-enheter." }, - "duoDesc": { - "message": "Verifiera med Duo Security genom att använda Duo Mobile-appen, SMS, telefonsamtal eller en U2F-säkerhetsnyckel.", + "duoDescV2": { + "message": "Ange en kod som genererats av Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Verifieringskoder kommer att skickas till dig via e-post." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Inloggning ej tillgänglig" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Bekräfta fillösenord" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Flerfaktorsautentisering avbruten" }, diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index 767619b10f4..0887d769823 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Master password confirmation does not match." - }, - "newAccountCreated": { - "message": "Your new account has been created! You may now log in." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Master password confirmation does not match." + }, + "newAccountCreated": { + "message": "Your new account has been created! You may now log in." + }, "masterPassSent": { "message": "We've sent you an email with your master password hint." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Login unavailable" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index 43a8688cf25..8c0a06ec424 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "การยืนยันรหัสผ่านหลักไม่ตรงกัน" - }, - "newAccountCreated": { - "message": "บัญชีใหม่ของคุณถูกสร้างขึ้นแล้ว! ตอนนี้คุณสามารถเข้าสู่ระบบ" - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "การยืนยันรหัสผ่านหลักไม่ตรงกัน" + }, + "newAccountCreated": { + "message": "บัญชีใหม่ของคุณถูกสร้างขึ้นแล้ว! ตอนนี้คุณสามารถเข้าสู่ระบบ" + }, "masterPassSent": { "message": "เราได้ส่งอีเมลพร้อมคำใบ้รหัสผ่านหลักของคุณ" }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "แอป Authenticator" }, - "authenticatorAppDesc": { - "message": "ใช้แอปตรวจสอบความถูกต้อง (เช่น Authy หรือ Google Authenticator) เพื่อสร้างรหัสยืนยันตามเวลา", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "ใช้ YubiKey เพื่อเข้าถึงบัญชีของคุณ ทำงานร่วมกับอุปกรณ์ YubiKey 4, 4 Nano, 4C และ NEO" }, - "duoDesc": { - "message": "ยืนยันด้วย Duo Security โดยใช้แอป Duo Mobile, SMS, โทรศัพท์ หรือคีย์ความปลอดภัย U2F", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "อีเมล" }, - "emailDesc": { - "message": "รหัสยืนยันจะถูกส่งถึงคุณทางอีเมลแล้ว" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "เข้าสู่ระบบไม่พร้อมใช้งาน" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 85f1db15d3c..b44135e8d43 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Parola ve parola onayı eşleşmiyor." - }, - "newAccountCreated": { - "message": "Yeni hesabınız oluşturuldu! Şimdi giriş yapabilirsiniz." - }, "youSuccessfullyLoggedIn": { "message": "Başarıyla giriş yaptınız" }, "youMayCloseThisWindow": { "message": "Bu pencereyi kapatabilirsiniz" }, + "masterPassDoesntMatch": { + "message": "Parola ve parola onayı eşleşmiyor." + }, + "newAccountCreated": { + "message": "Yeni hesabınız oluşturuldu! Şimdi giriş yapabilirsiniz." + }, "masterPassSent": { "message": "Size ana parolanızın ipucunu içeren bir e-posta gönderdik." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Kimlik doğrulama uygulaması" }, - "authenticatorAppDesc": { - "message": "Zamana dayalı doğrulama kodları oluşturmak için bir kimlik doğrulayıcı uygulaması (Authy veya Google Authenticator gibi) kullanın.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP güvenlik anahtarı" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Hesabınıza erişmek için bir YubiKey kullanın. YubiKey 4, 4 Nano, 4C ve NEO cihazlarıyla çalışır." }, - "duoDesc": { - "message": "Duo Security ile doğrulama için Duo Mobile uygulaması, SMS, telefon görüşmesi veya U2F güvenlik anahtarını kullanın.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "E-posta" }, - "emailDesc": { - "message": "Doğrulama kodu size e-postalanacak." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Giriş yapılamıyor" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Dosya parolasını onaylayın" }, + "exportSuccess": { + "message": "Kasa verileri dışa aktarıldı" + }, "multifactorAuthenticationCancelled": { "message": "Çok faktörlü kimlik doğrulama iptal edildi" }, diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 6dd1b4921ca..42c72e18bbb 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Підтвердження головного пароля не збігається." - }, - "newAccountCreated": { - "message": "Ваш обліковий запис створений! Тепер ви можете увійти." - }, "youSuccessfullyLoggedIn": { "message": "Ви успішно увійшли в систему" }, "youMayCloseThisWindow": { "message": "Можете закрити це вікно" }, + "masterPassDoesntMatch": { + "message": "Підтвердження головного пароля не збігається." + }, + "newAccountCreated": { + "message": "Ваш обліковий запис створений! Тепер ви можете увійти." + }, "masterPassSent": { "message": "Ми надіслали вам лист з підказкою для головного пароля." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Програма автентифікації" }, - "authenticatorAppDesc": { - "message": "Використовуйте програму автентифікації (наприклад, Authy або Google Authenticator), щоб генерувати тимчасові коди підтвердження.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Введіть код, згенерований програмою для автентифікації, як-от Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ безпеки YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Ключ безпеки Yubico OTP" }, "yubiKeyDesc": { "message": "Використовуйте YubiKey для доступу до сховища. Працює з YubiKey 4, 4 Nano, 4C та пристроями NEO." }, - "duoDesc": { - "message": "Авторизуйтесь за допомогою Duo Security з використанням мобільного додатку Duo Mobile, SMS, телефонного виклику, або ключа безпеки U2F.", + "duoDescV2": { + "message": "Введіть код, згенерований Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Е-пошта" }, - "emailDesc": { - "message": "Коди підтвердження будуть надсилатися на вашу пошту." + "emailDescV2": { + "message": "Введіть код, надісланий вам електронною поштою." }, "loginUnavailable": { "message": "Вхід недоступний" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Підтвердьте пароль файлу" }, + "exportSuccess": { + "message": "Дані сховища експортовано" + }, "multifactorAuthenticationCancelled": { "message": "Багатофакторну автентифікацію скасовано" }, diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index e3fe91447f9..6e155b82a75 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "Xác nhận mật khẩu chính không khớp." - }, - "newAccountCreated": { - "message": "Tài khoản của bạn đã được tạo. Bạn có thể đăng nhập bây giờ." - }, "youSuccessfullyLoggedIn": { "message": "You successfully logged in" }, "youMayCloseThisWindow": { "message": "You may close this window" }, + "masterPassDoesntMatch": { + "message": "Xác nhận mật khẩu chính không khớp." + }, + "newAccountCreated": { + "message": "Tài khoản của bạn đã được tạo. Bạn có thể đăng nhập bây giờ." + }, "masterPassSent": { "message": "Chúng tôi đã gửi cho bạn email có chứa gợi ý mật khẩu chính của bạn." }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "Ứng dụng xác thực" }, - "authenticatorAppDesc": { - "message": "Sử dụng một ứng dụng xác thực (chẳng hạn như Authy hoặc Google Authenticator) để tạo các mã xác nhận theo thời gian thực.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Khóa bảo mật YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "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." }, - "duoDesc": { - "message": "Xác minh với Duo Security 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.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Mã xác thực sẽ được gửi qua email cho bạn." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "Đăng nhập không sẵn có" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" }, diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index b75c2e04c56..ba9162b1d4e 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -503,7 +503,7 @@ "message": "设置强密码" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "设置密码后就能完成账户创建" + "message": "设置密码以完成账户的创建" }, "logIn": { "message": "登录" @@ -527,7 +527,7 @@ "message": "主密码提示(可选)" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "如果您忘记了密码,可以发送密码提示到您的电子邮箱。$CURRENT$ / 最多 $MAXIMUM$ 个字符。", "placeholders": { "current": { "content": "$1", @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "两次填写的主密码不一致。" - }, - "newAccountCreated": { - "message": "您的新账户已创建!您现在可以登录了。" - }, "youSuccessfullyLoggedIn": { "message": "您已成功登录" }, "youMayCloseThisWindow": { "message": "您可以关闭此窗口" }, + "masterPassDoesntMatch": { + "message": "两次填写的主密码不一致。" + }, + "newAccountCreated": { + "message": "您的新账户已创建!您现在可以登录了。" + }, "masterPassSent": { "message": "我们已经为您发送了包含主密码提示的邮件。" }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "验证器 App" }, - "authenticatorAppDesc": { - "message": "使用验证器 App(例如 Authy 或 Google Authenticator)来生成基于时间的验证码。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 安全钥匙" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "使用 YubiKey 来访问您的账户。支持 YubiKey 4、4 Nano、4C 以及 NEO 设备。" }, - "duoDesc": { - "message": "使用 Duo Security 的 Duo 移动应用、短信、电话或 U2F 安全钥匙来进行验证。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "电子邮件" }, - "emailDesc": { - "message": "验证码将会发送到您的电子邮箱。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "登录不可用" @@ -763,7 +763,7 @@ "message": "覆盖密码" }, "learnMore": { - "message": "了解更多" + "message": "进一步了解" }, "featureUnavailable": { "message": "功能不可用" @@ -1148,7 +1148,7 @@ "message": "感谢您支持 Bitwarden。" }, "premiumPrice": { - "message": "每年只需 $PRICE$ !", + "message": "只需 $PRICE$ /年!", "placeholders": { "price": { "content": "$1", @@ -2706,7 +2706,7 @@ "message": "子菜单" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "切换侧边导航" }, "skipToContent": { "message": "跳转到内容" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "确认文件密码" }, + "exportSuccess": { + "message": "密码库数据已导出" + }, "multifactorAuthenticationCancelled": { "message": "多重身份验证已取消" }, diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index e981434905d..75ac7dfb3fe 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -573,18 +573,18 @@ } } }, - "masterPassDoesntMatch": { - "message": "兩次填入的主密碼不一致。" - }, - "newAccountCreated": { - "message": "帳戶已建立!現在可以登入了。" - }, "youSuccessfullyLoggedIn": { "message": "你已成功登入" }, "youMayCloseThisWindow": { "message": "你可以關閉此視窗" }, + "masterPassDoesntMatch": { + "message": "兩次填入的主密碼不一致。" + }, + "newAccountCreated": { + "message": "帳戶已建立!現在可以登入了。" + }, "masterPassSent": { "message": "已寄出包含您主密碼提示的電子郵件。" }, @@ -666,18 +666,18 @@ "authenticatorAppTitle": { "message": "驗證器應用程式" }, - "authenticatorAppDesc": { - "message": "使用驗證器應用程式(如 Authy 或 Google Authenticator)產生基於時間的驗證碼。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 安全鑰匙" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "使用 YubiKey 來存取您的帳戶。支援 YubiKey 4、4 Nano、4C、以及 NEO 裝置。" }, - "duoDesc": { - "message": "使用 Duo Security 的 Duo Mobile 程式、SMS 、致電或 U2F 安全鑰匙進行驗證。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -693,8 +693,8 @@ "emailTitle": { "message": "電子郵件" }, - "emailDesc": { - "message": "使用電子郵件傳送驗證碼給您。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "loginUnavailable": { "message": "登入無法使用" @@ -2843,6 +2843,9 @@ "confirmFilePassword": { "message": "確認檔案密碼" }, + "exportSuccess": { + "message": "Vault data exported" + }, "multifactorAuthenticationCancelled": { "message": "多因素驗證已取消" }, From 383a4851b6755b959f91774d8e9b60991122e471 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Fri, 28 Jun 2024 15:35:10 +0200 Subject: [PATCH 031/130] Add auto submit on identifier query parameter (#9803) --- apps/web/src/app/auth/sso.component.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/web/src/app/auth/sso.component.ts b/apps/web/src/app/auth/sso.component.ts index 69bfd0a8c48..b1b22ecafcc 100644 --- a/apps/web/src/app/auth/sso.component.ts +++ b/apps/web/src/app/auth/sso.component.ts @@ -1,6 +1,7 @@ import { Component } from "@angular/core"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; +import { firstValueFrom } from "rxjs"; import { first } from "rxjs/operators"; import { SsoComponent as BaseSsoComponent } from "@bitwarden/angular/auth/components/sso.component"; @@ -92,6 +93,7 @@ export class SsoComponent extends BaseSsoComponent { if (qParams.identifier != null) { // SSO Org Identifier in query params takes precedence over claimed domains this.identifierFormControl.setValue(qParams.identifier); + await this.submit(); } else { // Note: this flow is written for web but both browser and desktop // redirect here on SSO button click. @@ -145,11 +147,21 @@ export class SsoComponent extends BaseSsoComponent { return; } + const autoSubmit = (await firstValueFrom(this.route.queryParams)).identifier != null; + this.identifier = this.identifierFormControl.value; await this.ssoLoginService.setOrganizationSsoIdentifier(this.identifier); if (this.clientId === "browser") { document.cookie = `ssoHandOffMessage=${this.i18nService.t("ssoHandOff")};SameSite=strict`; } - await Object.getPrototypeOf(this).submit.call(this); + try { + await Object.getPrototypeOf(this).submit.call(this); + } catch (error) { + if (autoSubmit) { + await this.router.navigate(["/login"]); + } else { + this.validationService.showError(error); + } + } }; } From 27070eb0311b4e986549748db280cbcecd6e8c1d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:07:02 +0000 Subject: [PATCH 032/130] Autosync the updated translations (#9864) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 57 +++++++++++-- apps/browser/src/_locales/az/messages.json | 83 ++++++++++++++----- apps/browser/src/_locales/be/messages.json | 57 +++++++++++-- apps/browser/src/_locales/bg/messages.json | 59 ++++++++++--- apps/browser/src/_locales/bn/messages.json | 57 +++++++++++-- apps/browser/src/_locales/bs/messages.json | 57 +++++++++++-- apps/browser/src/_locales/ca/messages.json | 57 +++++++++++-- apps/browser/src/_locales/cs/messages.json | 67 +++++++++++---- apps/browser/src/_locales/cy/messages.json | 57 +++++++++++-- apps/browser/src/_locales/da/messages.json | 65 ++++++++++++--- apps/browser/src/_locales/de/messages.json | 59 ++++++++++--- apps/browser/src/_locales/el/messages.json | 57 +++++++++++-- apps/browser/src/_locales/en_GB/messages.json | 57 +++++++++++-- apps/browser/src/_locales/en_IN/messages.json | 57 +++++++++++-- apps/browser/src/_locales/es/messages.json | 59 ++++++++++--- apps/browser/src/_locales/et/messages.json | 57 +++++++++++-- apps/browser/src/_locales/eu/messages.json | 57 +++++++++++-- apps/browser/src/_locales/fa/messages.json | 57 +++++++++++-- apps/browser/src/_locales/fi/messages.json | 61 +++++++++++--- apps/browser/src/_locales/fil/messages.json | 57 +++++++++++-- apps/browser/src/_locales/fr/messages.json | 81 +++++++++++++----- apps/browser/src/_locales/gl/messages.json | 57 +++++++++++-- apps/browser/src/_locales/he/messages.json | 57 +++++++++++-- apps/browser/src/_locales/hi/messages.json | 63 +++++++++++--- apps/browser/src/_locales/hr/messages.json | 57 +++++++++++-- apps/browser/src/_locales/hu/messages.json | 57 +++++++++++-- apps/browser/src/_locales/id/messages.json | 57 +++++++++++-- apps/browser/src/_locales/it/messages.json | 57 +++++++++++-- apps/browser/src/_locales/ja/messages.json | 57 +++++++++++-- apps/browser/src/_locales/ka/messages.json | 57 +++++++++++-- apps/browser/src/_locales/km/messages.json | 57 +++++++++++-- apps/browser/src/_locales/kn/messages.json | 57 +++++++++++-- apps/browser/src/_locales/ko/messages.json | 57 +++++++++++-- apps/browser/src/_locales/lt/messages.json | 57 +++++++++++-- apps/browser/src/_locales/lv/messages.json | 69 +++++++++++---- apps/browser/src/_locales/ml/messages.json | 57 +++++++++++-- apps/browser/src/_locales/mr/messages.json | 57 +++++++++++-- apps/browser/src/_locales/my/messages.json | 57 +++++++++++-- apps/browser/src/_locales/nb/messages.json | 57 +++++++++++-- apps/browser/src/_locales/ne/messages.json | 57 +++++++++++-- apps/browser/src/_locales/nl/messages.json | 55 ++++++++++-- apps/browser/src/_locales/nn/messages.json | 57 +++++++++++-- apps/browser/src/_locales/or/messages.json | 57 +++++++++++-- apps/browser/src/_locales/pl/messages.json | 57 +++++++++++-- apps/browser/src/_locales/pt_BR/messages.json | 57 +++++++++++-- apps/browser/src/_locales/pt_PT/messages.json | 59 ++++++++++--- apps/browser/src/_locales/ro/messages.json | 57 +++++++++++-- apps/browser/src/_locales/ru/messages.json | 59 ++++++++++--- apps/browser/src/_locales/si/messages.json | 57 +++++++++++-- apps/browser/src/_locales/sk/messages.json | 59 ++++++++++--- apps/browser/src/_locales/sl/messages.json | 57 +++++++++++-- apps/browser/src/_locales/sr/messages.json | 59 ++++++++++--- apps/browser/src/_locales/sv/messages.json | 57 +++++++++++-- apps/browser/src/_locales/te/messages.json | 57 +++++++++++-- apps/browser/src/_locales/th/messages.json | 57 +++++++++++-- apps/browser/src/_locales/tr/messages.json | 57 +++++++++++-- apps/browser/src/_locales/uk/messages.json | 59 ++++++++++--- apps/browser/src/_locales/vi/messages.json | 57 +++++++++++-- apps/browser/src/_locales/zh_CN/messages.json | 67 +++++++++++---- apps/browser/src/_locales/zh_TW/messages.json | 57 +++++++++++-- apps/browser/store/locales/lv/copy.resx | 52 ++++++------ 61 files changed, 2963 insertions(+), 623 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 0cd5a35db06..12fa9621c43 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "تطبيق المصادقة" }, - "authenticatorAppDesc": { - "message": "استخدام تطبيق مصادقة (مثل Authy أو Google Authenticator) لإنشاء رموز تحقق مستندة إلى الوقت.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "مفتاح أمان YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "استخدم YubiKey للوصول إلى حسابك. يعمل مع YubiKey 4 ،4 Nano ،4C، وأجهزة NEO." }, - "duoDesc": { - "message": "التحقق باستخدام نظام الحماية الثنائي باستخدام تطبيق Duo Mobile أو الرسائل القصيرة أو المكالمة الهاتفية أو مفتاح الأمان U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "البريد الإلكتروني" }, - "emailDesc": { - "message": "سيتم إرسال رمز التحقق إليك بالبريد الإلكتروني." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "البيئة المستضافة ذاتيا" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "تأكيد كلمة مرور الملف" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 4a01675331d..0dd87713dbe 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -123,7 +123,7 @@ "message": "Parol yarat (kopyalandı)" }, "copyElementIdentifier": { - "message": "Özəl sahə adını kopyala" + "message": "Özəl xana adını kopyala" }, "noMatchingLogins": { "message": "Uyuşan giriş məlumatları yoxdur" @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Kimlik doğrulayıcı tətbiqi" }, - "authenticatorAppDesc": { - "message": "Vaxt əsaslı doğrulama kodları yaratmaq üçün (Authy və ya Google Authenticator kimi) kimlik doğrulayıcı tətbiq istifadə edin.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP güvənlik açarı" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Hesabınıza müraciət etmək üçün bir YubiKey istifadə edin. YubiKey 4, 4 Nano, 4C və NEO cihazları ilə işləyir." }, - "duoDesc": { - "message": "Duo Security ilə doğrulamaq üçün Duo Mobile tətbiqi, SMS, telefon zəngi və ya U2F güvənlik açarını istifadə edin.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,17 +1132,17 @@ "emailTitle": { "message": "E-poçt" }, - "emailDesc": { - "message": "Doğrulama kodları e-poçt ünvanınıza göndəriləcək." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { - "message": "Öz-özünə sahiblik edən mühit" + "message": "Self-hosted mühit" }, "selfHostedEnvironmentFooter": { - "message": "Öz-özünə sahiblik edən Bitwarden quraşdırmasının baza URL-sini müəyyənləşdirin." + "message": "Öz-özünə sahiblik edən Bitwarden quraşdırmasının təməl URL-sini müəyyənləşdirin." }, "selfHostedBaseUrlHint": { - "message": "Şirkət daxili sahiblik edən Bitwarden quraşdırmasının təməl URL-sini qeyd edin. Nümunə: https://bitwarden.company.com" + "message": "Öz-özünə sahiblik edən Bitwarden quraşdırmasının təməl URL-sini müəyyənləşdirin. Nümunə: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { "message": "Qabaqcıl konfiqurasiya üçün hər xidmətin təməl URL-sini müstəqil olaraq qeyd edə bilərsiniz." @@ -1178,7 +1178,7 @@ "message": "Mühit URL-ləri saxlanıldı." }, "showAutoFillMenuOnFormFields": { - "message": "Form sahələrində avto-doldurma menyusunu göstər", + "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": { @@ -1195,7 +1195,7 @@ "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "Sahə seçiləndə (fokusda)", + "message": "Xana seçildikdə (fokusda)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { @@ -1248,7 +1248,7 @@ "message": "Anbarı kilidlə" }, "customFields": { - "message": "Özəl sahələr" + "message": "Özəl xanalar" }, "copyValue": { "message": "Dəyəri kopyala" @@ -1257,7 +1257,7 @@ "message": "Dəyər" }, "newCustomField": { - "message": "Yeni özəl sahə" + "message": "Yeni özəl xana" }, "dragToSort": { "message": "Sıralamaq üçün sürüklə" @@ -2265,7 +2265,7 @@ "message": "Unikal identifikator tapılmadı." }, "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$, öz-özünə sahiblik edən açar serveri ilə SSO istifadə edir. Bu təşkilatın üzvlərinin giriş etməsi üçün artıq ana parol tələb edilməyəcək.", + "message": "$ORGANIZATION$, self-hosted açar serveri ilə SSO istifadə edir. Bu təşkilatın üzvlərinin giriş etməsi üçün artıq ana parol tələb edilməyəcək.", "placeholders": { "organization": { "content": "$1", @@ -2513,7 +2513,7 @@ "message": "Server versiyası" }, "selfHostedServer": { - "message": "öz-özünə sahiblik edən" + "message": "self-hosted" }, "thirdParty": { "message": "Üçüncü tərəf" @@ -2803,7 +2803,7 @@ "message": "Giriş, bir e-poçt ünvanı deyil." }, "fieldsNeedAttention": { - "message": "Yuxarıdakı $COUNT$ sahənin diqqətinizə ehtiyacı var.", + "message": "Yuxarıdakı $COUNT$ xananın diqqətinizə ehtiyacı var.", "placeholders": { "count": { "content": "$1", @@ -2886,7 +2886,7 @@ "description": "Toast message for informing the user that auto-fill on page load has been set to the default setting." }, "turnOffMasterPasswordPromptToEditField": { - "message": "Bu sahəyə düzəliş etmək üçün \"Ana parolu təkrar soruş\"u söndürün", + "message": "Bu xanaya düzəliş etmək üçün \"Ana parolu təkrar soruş\"u söndürün", "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Fayl parolunu təsdiqlə" }, + "exportSuccess": { + "message": "Anbar datası xaricə köçürüldü" + }, "typePasskey": { "message": "Keçid açarı" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Deaktiv edilmiş təşkilatlardakı elementlərə müraciət edilə bilməz. Kömək üçün təşkilatınızın sahibi ilə əlaqə saxlayın." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { - "message": "Filters" + "message": "Filtrlər" } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 404324e3c15..d97f42a73cf 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Праграма аўтэнтыфікацыі" }, - "authenticatorAppDesc": { - "message": "Выкарыстоўвайце праграму праграму аўтэнтыфікацыі (напрыклад, Authy або Google Authenticator) для генерацыі праверачных кодаў на падставе часу.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ бяспекі YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Выкарыстоўвайце YubiKey для доступу да вашага ўліковага запісу. Працуе з ключамі бяспекі YubiKey 4, 4 Nano, 4C і NEO." }, - "duoDesc": { - "message": "Праверка з дапамогай Duo Security, выкарыстоўваючы праграму Duo Mobile, SMS, тэлефонны выклік або ключ бяспекі U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Электронная пошта" }, - "emailDesc": { - "message": "Праверачныя коды будуць адпраўляцца вам па электронную пошту." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Асяроддзе ўласнага хостынгу" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Пацвердзіць пароль файла" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 4d769bfa0c6..25e4c4c43dd 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Приложение за удостоверяване" }, - "authenticatorAppDesc": { - "message": "Използвайте приложение за удостоверяване (като Authy или Google Authenticator) за генерирането на временни кодове за потвърждение.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ за сигурност YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Използвайте ключа за сигурност YubiKey, за да влезете в акаунта си. Работи с устройствата YubiKey 4, 4 Nano, 4C и NEO." }, - "duoDesc": { - "message": "Удостоверяване чрез Duo Security, с ползване на приложението Duo Mobile, SMS, телефонен разговор или устройство U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Електронна поща" }, - "emailDesc": { - "message": "Кодовете за потвърждение ще ви бъдат пратени по е-поща." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Собствена среда" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Потвърждаване на паролата на файла" }, + "exportSuccess": { + "message": "Данните от трезора са изнесени" + }, "typePasskey": { "message": "Секретен ключ" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Записите в деактивирани организации не са достъпни. Свържете се със собственика на организацията си за помощ." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { - "message": "Filters" + "message": "Филтри" } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 8c5db7d4936..d0eaa8b5919 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "প্রমাণীকরণকারী অ্যাপ" }, - "authenticatorAppDesc": { - "message": "সময় ভিত্তিক যাচাইকরণ কোড উৎপন্ন করতে একটি প্রমাণীকরণকারী অ্যাপ্লিকেশন (যেমন Authy বা Google Authenticator) ব্যবহার করুন।", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP সুরক্ষা কী" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "আপনার অ্যাকাউন্ট ব্যাবহার করতে একটি YubiKey ব্যবহার করুন। YubiKey 4, 4 Nano, 4C, এবং NEO ডিভাইসগুলির সাথে কাজ করে।" }, - "duoDesc": { - "message": "Duo Mobile app, এসএমএস, ফোন কল, বা U2F সুরক্ষা কী ব্যবহার করে Duo Security এর মাধ্যমে যাচাই করুন।", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "ই-মেইল" }, - "emailDesc": { - "message": "যাচাই কোডগুলি আপনাকে ই-মেইল করা হবে।" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "স্ব-হোস্টকৃত পরিবেশ" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index f49a9148aec..116e27b5009 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 00b4088eb7a..0298def3c7c 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplicació autenticadora" }, - "authenticatorAppDesc": { - "message": "Utilitzeu una aplicació autenticadora (com Authy o Google Authenticator) per generar codis de verificació basats en el temps.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Clau de seguretat OTP de YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Utilitzeu una YubiKey per accedir al vostre compte. Funciona amb els dispositius YubiKey 4, 4 Nano, 4C i NEO." }, - "duoDesc": { - "message": "Verifiqueu amb Duo Security mitjançant l'aplicació Duo Mobile, SMS, trucada telefònica o clau de seguretat U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Correu electrònic" }, - "emailDesc": { - "message": "Els codis de verificació els rebreu per correu electrònic." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Entorn d'allotjament propi" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirma la contrasenya del fitxer" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Clau de pas" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index 8f0d3901d65..cf28c93bab9 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -409,7 +409,7 @@ "message": "Oblíbené" }, "unfavorite": { - "message": "Unfavorite" + "message": "Odebrat z oblíbených" }, "itemAddedToFavorites": { "message": "Položka byla přidána do oblíbených" @@ -439,7 +439,7 @@ "message": "Spustit" }, "launchWebsite": { - "message": "Launch website" + "message": "Otevřít webovou stránku" }, "website": { "message": "Webová stránka" @@ -591,7 +591,7 @@ "message": "Byli jste úspěšně přihlášeni" }, "youMayCloseThisWindow": { - "message": "Nyní můžete toto okno zavřít" + "message": "Toto okno můžete zavřít" }, "masterPassSent": { "message": "Poslali jsme Vám e-mail s nápovědou k hlavnímu heslu." @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Ověřovací aplikace" }, - "authenticatorAppDesc": { - "message": "Použijte ověřovací aplikaci (jako je Authy nebo Google Authenticator) pro generování časově omezených kódů.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Zadejte kód vygenerovaný ověřovací aplikací, jako je Autentikátor Bitwarden.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { + "yubiKeyTitleV2": { "message": "Bezpečnostní klíč YubiKey OTP" }, "yubiKeyDesc": { "message": "Použije YubiKey pro přístup k Vašemu trezoru. Podporuje YubiKey 4, 4 Nano, 4C a NEO." }, - "duoDesc": { - "message": "Ověření pomocí Duo Security prostřednictvím aplikace Duo Mobile, SMS, telefonního hovoru nebo bezpečnostního klíče U2F.", + "duoDescV2": { + "message": "Zadejte kód vygenerovaný DUO Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Ověřovací kódy Vám budou zaslány e-mailem." + "emailDescV2": { + "message": "Zadejte kód odeslaný na Váš e-mail." }, "selfHostedEnvironment": { "message": "Vlastní hostované prostředí" @@ -1481,7 +1481,7 @@ "message": "Kolekce" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ kolekcí", "placeholders": { "count": { "content": "$1", @@ -1719,7 +1719,7 @@ "message": "Automaticky vyplnit a uložit" }, "fillAndSave": { - "message": "Fill and save" + "message": "Vyplnit a uložit" }, "autoFillSuccessAndSavedUri": { "message": "Položka byla automaticky vyplněna a URI bylo uloženo" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Potvrzení hesla souboru" }, + "exportSuccess": { + "message": "Data trezoru byla exportována" + }, "typePasskey": { "message": "Přístupový klíč" }, @@ -3424,7 +3427,7 @@ "message": "Žádné hodnoty ke zkopírování" }, "assignCollections": { - "message": "Assign collections" + "message": "Přiřadit kolekce" }, "copyEmail": { "message": "Kopírovat e-mail" @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "K položkám v deaktivované organizaci nemáte přístup. Požádejte o pomoc vlastníka organizace." }, + "upload": { + "message": "Nahrát" + }, + "addAttachment": { + "message": "Přidat přílohu" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximální velikost souboru je 500 MB" + }, + "deleteAttachmentName": { + "message": "Smazat přílohu $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Stáhnout $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Opravdu chcete tuto přílohu navždy smazat?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Volné organizace nemohou používat přílohy" + }, "filters": { "message": "Filtry" } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 38a276406ac..ac449edac8d 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Ap dilysu" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Ebost" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index cb525a2373c..98d5c9eeb0e 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentificerings-app" }, - "authenticatorAppDesc": { - "message": "Brug en autentificerings app (f.eks. Authy eller Google Autentificering) til at generere tidsbaserede bekræftelseskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Angiv en kode genereret af en godkendelses-app såsom Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP sikkerhedsnøgle" + "yubiKeyTitleV2": { + "message": "Yubico OTP-sikkerhedsnøgle" }, "yubiKeyDesc": { "message": "Brug en YubiKey til at få adgang til din konto. Virker med YubiKey 4, 4 Nano, 4C og NEO enheder." }, - "duoDesc": { - "message": "Bekræft med Duo sikkerhed ved hjælp af Duo Mobile app, SMS, telefonopkald eller U2F sikkerhedsnøgle.", + "duoDescV2": { + "message": "Angiv en kode genereret af Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Bekræftelseskoder vil blive e-mailet til dig." + "emailDescV2": { + "message": "Angiv en kode tilsendt pr. e-mail." }, "selfHostedEnvironment": { "message": "Selv-hosted miljø" @@ -1142,13 +1142,13 @@ "message": "Angiv grund-URL'en i din lokal-hostede Bitwarden-installation." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Angiv basis-URL'en for den lokalt-hosted Bitwarden-installation. Eks.: https://bitwarden.firma.dk" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Til avancerede brugere. Man kan angive basis-URL'en for hver tjeneste uafhængigt." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Der skal tilføjes enten basis server-URL'en eller mindst ét tilpasset miljø." }, "customEnvironment": { "message": "Brugerdefineret miljø" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Bekræft filadgangskode" }, + "exportSuccess": { + "message": "Boksdata eksporteret" + }, "typePasskey": { "message": "Adgangsnøgle" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Emner i deaktiverede organisationer kan ikke tilgås. Kontakt organisationsejeren for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Tilføj vedhæftning" + }, + "maxFileSizeSansPunctuation": { + "message": "Maks. filstørrelse er 500 MB" + }, + "deleteAttachmentName": { + "message": "Slet vedhæftelse $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Sikker på, at denne vedhæftning skal slettes permanent?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Gratis organisationer kan ikke bruge vedhæftninger" + }, "filters": { - "message": "Filters" + "message": "Filtre" } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index ef1ebaf21eb..b8bed8ae117 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -17,7 +17,7 @@ "message": "Konto erstellen" }, "setAStrongPassword": { - "message": "Ein starkes Passwort festlegen" + "message": "Lege ein starkes Passwort fest" }, "finishCreatingYourAccountBySettingAPassword": { "message": "Schließe die Erstellung deines Kontos ab, indem du ein Passwort festlegst" @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "authenticatorAppDesc": { - "message": "Verwende eine Authentifizierungs-App (wie zum Beispiel Authy oder Google Authenticator), um zeitbasierte Verifizierungscodes zu generieren.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Sicherheitsschlüssel" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Verwende einen YubiKey um auf dein Konto zuzugreifen. Funtioniert mit YubiKey 4, Nano 4, 4C und NEO Geräten." }, - "duoDesc": { - "message": "Verifiziere mit Duo Security, indem du die Duo Mobile App, SMS, Anrufe oder U2F Sicherheitsschlüssel benutzt.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-Mail" }, - "emailDesc": { - "message": "Bestätigungscodes werden Ihnen per E-Mail zugesandt." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Selbst gehostete Umgebung" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Dateipasswort bestätigen" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Auf Einträge in deaktivierten Organisationen kann nicht zugegriffen werden. Kontaktiere deinen Organisationseigentümer für Unterstützung." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filter" } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 8de4246422a..7a61e587ed5 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Εφαρμογή ελέγχου ταυτότητας" }, - "authenticatorAppDesc": { - "message": "Χρησιμοποιήστε μια εφαρμογή επαλήθευσης (όπως το Authy ή Google Authenticator) για να δημιουργήσει κωδικούς επαλήθευσης με χρόνικο περιορισμό.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Κλειδί ασφαλείας YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Χρησιμοποιήστε ένα YubiKey για να αποκτήσετε πρόσβαση στο λογαριασμό σας. Λειτουργεί με συσκευές σειράς YubiKey 4, 4 Nano, 4C και συσκευές NEO." }, - "duoDesc": { - "message": "Επαληθεύστε με το Duo Security χρησιμοποιώντας την εφαρμογή Duo Mobile, μηνύματα SMS, τηλεφωνική κλήση ή κλειδί ασφαλείας U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Οι κωδικοί επαλήθευσης θα σας αποσταλούν μέσω ηλεκτρονικού ταχυδρομείου." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Αυτο-φιλοξενούμενο περιβάλλον" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Επιβεβαίωση κωδικού πρόσβασης αρχείου" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 4cf3cfcfcb6..691d8d7a15d 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organisations cannot be accessed. Contact your organisation owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organisations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 40613be7088..4ed0406a282 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organisations cannot be accessed. Contact your organisation owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organisations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index 29351836665..9dfdb4acda1 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplicación de autenticación" }, - "authenticatorAppDesc": { - "message": "Utiliza una aplicación de autenticación (como Authy o Google Authenticator) para generar código de verificación basados en tiempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Llave de seguridad YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Usa un Yubikey para acceder a tu cuenta. Funciona con YubiKey 4, 4 Nano, 4C y dispositivos NEO." }, - "duoDesc": { - "message": "Verificar con Duo Security usando la aplicación Duo Mobile, SMS, llamada telefónica o llave de seguridad U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Correo electrónico" }, - "emailDesc": { - "message": "Los códigos de verificación te serán enviados por correo electrónico." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Entorno de alojamiento propio" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirmar contraseña del archivo" }, + "exportSuccess": { + "message": "Datos de la caja fuerte exportados" + }, "typePasskey": { "message": "Clave de acceso" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "No se puede acceder a los elementos de las organizaciones desactivadas. Ponte en contacto con el propietario de tu organización para obtener ayuda." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { - "message": "Filters" + "message": "Filtros" } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 498d90a5fdd..1772f91a6c1 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentimise rakendus" }, - "authenticatorAppDesc": { - "message": "Kausta autentimise rakendust (näiteks Authy või Google Authenticator), et luua ajal baseeruvaid kinnituskoode.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Turvaline võti" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Kasuta kontole ligipääsemiseks YubiKey-d. See töötab YubiKey 4, 4 Nano, 4C ja NEO seadmetega." }, - "duoDesc": { - "message": "Kinnita Duo Security abil, kasutades selleks Duo Mobile rakendust, SMS-i, telefonikõnet või U2F turvavõtit.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Kinnituskoodid saadetakse e-postiga." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted Environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 0dd330314a0..ef3c2e1a54a 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentifikazio aplikazioa" }, - "authenticatorAppDesc": { - "message": "Erabili autentifikazio aplikazio bat (adibidez, Authy edo Google Authenticator) denboran oinarritutako egiaztatze-kodeak sortzeko.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP segurtasun-gakoa" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Erabili YubiKey zure kontuan sartzeko. YubiKey 4, 4 Nano, 4C eta NEO gailuekin dabil." }, - "duoDesc": { - "message": "Egiaztatu Duo Securityrekin Duo Mobile aplikazioa, SMS, telefono deia edo U2F segurtasun-gakoa erabiliz.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Emaila" }, - "emailDesc": { - "message": "Egiaztatze-kodeak email bidez bidaliko dira." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Ostatze ingurune propioa" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 44d9e193df3..4ee10ae5d0a 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "برنامه احراز هویت" }, - "authenticatorAppDesc": { - "message": "از یک برنامه احراز هویت (مانند Authy یا Google Authenticator) استفاده کنید تا کدهای تأیید بر پایه زمان تولید کنید.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "کلید امنیتی YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "از یک YubiKey برای دسترسی به حسابتان استفاده کنید. همراه با دستگاه‌های YubiKey 4 ،4 Nano ،NEO کار می‌کند." }, - "duoDesc": { - "message": "با Duo Security با استفاده از برنامه تلفن همراه، پیامک، تماس تلفنی، یا کلید امنیتی U2F تأیید کنید.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "ایمیل" }, - "emailDesc": { - "message": "کد تأیید برایتان ارسال می‌شود." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "محیط خود میزبان" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 5892908f5e4..0ef0c055fe4 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Todennussovellus" }, - "authenticatorAppDesc": { - "message": "Käytä todennussovellusta (kuten Authy, Google tai Microsoft Authenticator) luodaksesi aikarajallisia todennuskoodeja.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP -todennuslaite" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Käytä YubiKey-todennuslaitetta tilisi avaukseen. Toimii YubiKey 4, 4 Nano, 4C sekä NEO -laitteiden kanssa." }, - "duoDesc": { - "message": "Vahvista Duo Securityn avulla käyttäen Duo Mobile ‑sovellusta, tekstiviestiä, puhelua tai U2F-todennuslaitetta.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Sähköposti" }, - "emailDesc": { - "message": "Todennuskoodit lähetetään sinulle sähköpostitse." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Itse ylläpidetty palvelinympäristö" @@ -2890,7 +2890,7 @@ "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äytä/piilota sivuvalikko" }, "skipToContent": { "message": "Siirry sisältöön" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Vahvista tiedoston salasana" }, + "exportSuccess": { + "message": "Holvin tiedot on viety" + }, "typePasskey": { "message": "Suojausavain" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Käytöstä poistettujen organisaatioiden kohteet eivät ole käytettävissä. Ole yhteydessä organisaation omistajaan saadaksesi apua." }, + "upload": { + "message": "Lähetä" + }, + "addAttachment": { + "message": "Lisää liite" + }, + "maxFileSizeSansPunctuation": { + "message": "Tiedoston enimmäiskoko on 500 Mt" + }, + "deleteAttachmentName": { + "message": "Poista liite $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Lataa $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Haluatko varmasti poistaa tämän liitteen pysyvästi?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Ilmaiset organisaatiot eivät voi käyttää liitteitä" + }, "filters": { - "message": "Filters" + "message": "Suodattimet" } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index d477f3f75d2..9ccc3dd41d6 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "App ng Authenticator" }, - "authenticatorAppDesc": { - "message": "Gamitin ang isang authenticator app (tulad ng Authy o Google Authenticator) upang lumikha ng time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Gamitin ang YubiKey upang ma-access ang iyong account. Gumagana sa mga YubiKey 4, 4 Nano, 4C, at NEO devices." }, - "duoDesc": { - "message": "Patunayan sa pamamagitan ng Duo Security gamit ang Duo Mobile app, SMS, tawag sa telepono, o key ng seguridad ng U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Mag-email" }, - "emailDesc": { - "message": "Mga kodigong pang-pagpapatunay ang ipapadala sa iyo sa pamamagitan ng email." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Kapaligirang self-hosted" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 9c18144f2ef..f451419052b 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -17,10 +17,10 @@ "message": "Créer un compte" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Définir un mot de passe fort" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Terminer la création de votre compte en définissant un mot de passe" }, "login": { "message": "Se connecter" @@ -50,7 +50,7 @@ "message": "Un indice de mot de passe principal peut vous aider à vous souvenir de votre mot de passe si vous l'oubliez." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Si vous oubliez votre mot de passe, l'indice peut être envoyé à votre courriel. $CURRENT$/$MAXIMUM$ caractères maximum.", "placeholders": { "current": { "content": "$1", @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Application d'authentification" }, - "authenticatorAppDesc": { - "message": "Utiliser une application d'authentification (comme Authy ou Google Authenticator) pour générer des codes de vérification basés sur le temps.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Clé de sécurité YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Utiliser une YubiKey pour accéder à votre compte. Fonctionne avec les appareils YubiKey 4, 4 Nano, 4C et NEO." }, - "duoDesc": { - "message": "S'authentifier avec Duo Security via l'application Duo Mobile, un SMS, un appel téléphonique, ou une clé de sécurité U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Courriel" }, - "emailDesc": { - "message": "Les codes de vérification vous seront envoyés par courriel." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Environnement auto-hébergé" @@ -1454,7 +1454,7 @@ "message": "Identité" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "Nouveau/nouvelle $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1463,7 +1463,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Éditer $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1481,7 +1481,7 @@ "message": "Collections" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ collection(s)", "placeholders": { "count": { "content": "$1", @@ -1803,16 +1803,16 @@ "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Se désabonner" }, "atAnyTime": { - "message": "at any time." + "message": "à tout moment." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "En continuant, vous acceptez les" }, "and": { - "message": "and" + "message": "et" }, "acceptPolicies": { "message": "En cochant cette case vous acceptez ce qui suit :" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirmez le mot de passe du fichier" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Clé d'identification (passkey)" }, @@ -3421,7 +3424,7 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "Aucune valeur à copier" }, "assignCollections": { "message": "Assigner une collection" @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Les éléments des Organisations désactivées ne sont pas accessibles. Contactez le propriétaire de votre Organisation pour obtenir de l'aide." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { - "message": "Filters" + "message": "Filtres" } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 2e3c478cb54..bab28293b0f 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplicación de autenticación" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Correo electrónico" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Entorno de auto-aloxamento" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index e9bdad57d6e..0a256a01cc0 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "אפליקציית אימות" }, - "authenticatorAppDesc": { - "message": "השתמש באפליקצית אימות (כמו לדוגמא Authy או Google Authenticator) לייצור סיסמאות אימות מבוססות זמן.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "מפתח אבטחה OTP של YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "השתמש בYubiKey עבור גישה לחשבון שלך. עובד עם YubiKey בגירסאות 4, 4C, 4Nano, ומכשירי NEO." }, - "duoDesc": { - "message": "בצע אימות מול Duo Security באמצעות אפליקצית Duo לפלאפון, SMS, שיחת טלפון, או מפתח אבטחה U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "אימייל" }, - "emailDesc": { - "message": "קודי אימות ישלחו לאימייל שלך." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "סביבה על שרתים מקומיים" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 3442987a3d3..c907c1a1982 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -3,7 +3,7 @@ "message": "bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "बिटवार्डन पासवर्ड मैनेजर", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { @@ -224,7 +224,7 @@ "message": "Log Out" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "बिटवार्डन का परिचय" }, "about": { "message": "जानकारी" @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "authenticatorAppDesc": { - "message": "समय-आधारित सत्यापन कोड उत्पन्न करने के लिए एक प्रमाणक ऐप (जैसे Authy या Google Authenticator) का उपयोग करें।", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "अपने खाते तक पहुंचने के लिए YubiKey का उपयोग करें। YubiKey 4, 4 नैनो, 4C, और NEO उपकरणों के साथ काम करता है।" }, - "duoDesc": { - "message": "डुओ मोबाइल ऐप, एसएमएस, फोन कॉल या U2F सुरक्षा कुंजी का उपयोग करके डुओ सिक्योरिटी के साथ सत्यापित करें।", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "ईमेल" }, - "emailDesc": { - "message": "सत्यापन कोड आपको ईमेल किए जाएंगे।" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted Environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "वॉल्ट डेटा निर्यात किया गया" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { - "message": "Filters" + "message": "फ़िल्टर" } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 3067103d7be..188cab07b00 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentifikatorska aplikacija" }, - "authenticatorAppDesc": { - "message": "Koristi autentifikatorsku aplikaciju (npr. Authy ili Google Authentifikator) za generiranje kontrolnih kodova.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP sigurnosni ključ" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Koristi YubiKey za pristup svojem računu. Radi s YubiKey 4, 4 Nano, 4C i NEO uređajima." }, - "duoDesc": { - "message": "Potvrdi s Duo Security pomoću aplikacije Duo Mobile, SMS-om, telefonskim pozivom ili U2F sigurnosnim ključem.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-pošta" }, - "emailDesc": { - "message": "Verifikacijski kodovi će biti poslani e-poštom." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Vlastito hosting okruženje" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Potvrdi lozinku datoteke" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Pristupni ključ" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 3d457670136..b0bc1f06c8d 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Hitelesítő alkalmazás" }, - "authenticatorAppDesc": { - "message": "Használj egy másik alkalmazást (mint például az Authy vagy a Google Authenticator) idő alapú ellenőrzőkód generálásához.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Adjunk meg egy hitelesítő alkalmazás, például a Bitwarden Authenticator által generált kódot.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { + "yubiKeyTitleV2": { "message": "YubiKey OTP biztonsági kulcs" }, "yubiKeyDesc": { "message": "Használj egy YubiKey-t, hogy hozzá férhess a felhasználódhoz. Működik a YubiKey 4, 4 Nano, 4C, és NEO eszközökkel." }, - "duoDesc": { - "message": "Ellenőrizd Duo Security-val a Duo Mobile alkalmazás, SMS, telefon hívás vagy U2F biztonsági kulcs segítségével.", + "duoDescV2": { + "message": "Adjuk meg a Duo Security által generált kódot.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Ellenőrző kódok el lesznek e-mailbe küldve neked." + "emailDescV2": { + "message": "Adjuk meg az email címre elküldött kódot." }, "selfHostedEnvironment": { "message": "Saját üzemeltetésű környezet" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Fájl jelszó megerősítés" }, + "exportSuccess": { + "message": "A széfadatok exportálásra kerültek." + }, "typePasskey": { "message": "Hozzáférési kulcs" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Feltöltés" + }, + "addAttachment": { + "message": "Melléklet hozzáadása" + }, + "maxFileSizeSansPunctuation": { + "message": "A naximális fájlméret 500 MB." + }, + "deleteAttachmentName": { + "message": "$NAME$ melléklet törlése", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "$NAME$ letöltése", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Biztosan véglegesen törlésre kerüljön ez a melléklet?" + }, + "premium": { + "message": "Prémium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Az ingyenes szervezetek nem használhatnak mellékleteket." + }, "filters": { - "message": "Filters" + "message": "Szűrők" } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 28e11b71c83..e332db6a59e 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplikasi Otentikasi" }, - "authenticatorAppDesc": { - "message": "Gunakan aplikasi autentikasi (seperti Authy atau Google Authenticator) untuk menghasilkan kode verifikasi berbasis waktu.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Kunci Keamanan OTP YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Gunakan YubiKey untuk mengakses akun Anda. Bekerja dengan YubiKey 4, 4 Nano, 4C, dan peranti NEO." }, - "duoDesc": { - "message": "Verifikasi dengan Duo Security menggunakan aplikasi Duo Mobile, SMS, panggilan telepon, atau kunci keamanan U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Kode verifikasi akan dikirim via email kepada Anda." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Lingkungan Penyedia Personal" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index b7830b27ee8..43233eb67fd 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "App di autenticazione" }, - "authenticatorAppDesc": { - "message": "Usa un'app di autenticazione (come Authy o Google Authenticator) per generare codici di verifica basati sul tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chiave di sicurezza YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Usa YubiKey per accedere al tuo account. Funziona con YubiKey 4, 4 Nano, 4C, e dispositivi NEO." }, - "duoDesc": { - "message": "Verifica con Duo Security usando l'app Duo Mobile, SMS, chiamata telefonica, o chiave di sicurezza U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "I codici di verifica ti saranno inviati per email." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Ambiente self-hosted" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Conferma password del file" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Non puoi accedere agli elementi nelle organizzazioni disattivate. Contatta il proprietario della tua organizzazione per ricevere assistenza." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index a0075901f06..c2c839c32ee 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "認証アプリ" }, - "authenticatorAppDesc": { - "message": "Authy や Google 認証システムなどの認証アプリで時限式の認証コードを生成してください。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP セキュリティキー" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "YubiKey を使ってアカウントにアクセスできます。 YubiKey 4、4 Nano、4C、NEOに対応しています。" }, - "duoDesc": { - "message": "Duo Mobile アプリや SMS、電話や U2F セキュリティキーを使って Duo Security で認証します。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "メールアドレス" }, - "emailDesc": { - "message": "確認コードをメールにお送りします。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "セルフホスティング環境" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "ファイルパスワードの確認" }, + "exportSuccess": { + "message": "保管庫データをエクスポートしました" + }, "typePasskey": { "message": "パスキー" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "無効化された組織のアイテムにアクセスすることはできません。組織の所有者に連絡してください。" }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "フィルター" } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index b848a578063..eaa67e5067c 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index e4fc9c23f01..b091f15db64 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index d38a8d7ae76..ae98597d718 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್" }, - "authenticatorAppDesc": { - "message": "ಸಮಯ ಆಧಾರಿತ ಪರಿಶೀಲನಾ ಕೋಡ್‌ಗಳನ್ನು ರಚಿಸಲು ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸಿ (ಆಥಿ ಅಥವಾ ಗೂಗಲ್ ಅಥೆಂಟಿಕೇಟರ್).", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "ಯುಬಿಕೆ ಒಟಿಪಿ ಭದ್ರತಾ ಕೀ" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "ನಿಮ್ಮ ಖಾತೆಯನ್ನು ಪ್ರವೇಶಿಸಲು ಯುಬಿಕೆ ಬಳಸಿ. ಯುಬಿಕೆ 4, 4 ನ್ಯಾನೋ, 4 ಸಿ ಮತ್ತು ಎನ್ಇಒ ಸಾಧನಗಳೊಂದಿಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ." }, - "duoDesc": { - "message": "ಡ್ಯುಯೊ ಮೊಬೈಲ್ ಅಪ್ಲಿಕೇಶನ್, ಎಸ್‌ಎಂಎಸ್, ಫೋನ್ ಕರೆ ಅಥವಾ ಯು 2 ಎಫ್ ಭದ್ರತಾ ಕೀಲಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಡ್ಯುಯೊ ಸೆಕ್ಯುರಿಟಿಯೊಂದಿಗೆ ಪರಿಶೀಲಿಸಿ.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "ಇಮೇಲ್" }, - "emailDesc": { - "message": "ಪರಿಶೀಲನೆ ಕೋಡ್‌ಗಳನ್ನು ನಿಮಗೆ ಇಮೇಲ್ ಮಾಡಲಾಗುತ್ತದೆ." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "ಸ್ವಯಂ ಆತಿಥೇಯ ಪರಿಸರ" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index a7e5ce201a6..a0bcd750e3e 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "인증 앱" }, - "authenticatorAppDesc": { - "message": "인증 앱(Authy, Google OTP 등)을 통하여 일회용 인증 코드를 생성합니다.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 보안 키" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "YubiKey를 사용하여 사용자의 계정에 접근합니다. YubiKey 4, 4 Nano, 4C 및 NEO 기기를 사용할 수 있습니다." }, - "duoDesc": { - "message": "Duo Mobile 앱, SMS, 전화 통화를 사용한 Duo Security 또는 U2F 보안 키를 사용하여 인증하세요.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "이메일" }, - "emailDesc": { - "message": "인증 코드가 담긴 이메일을 다시 보냅니다." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "자체 호스팅 환경" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "패스키" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index c9e43d50556..1ed17a1a998 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentifikavimo programa" }, - "authenticatorAppDesc": { - "message": "Naudok autentifikatoriaus programėlę (pvz., Authy arba Google Autentifikatorius), kad sugeneruotum laiko patikrinimo kodus.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP saugumo raktas" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Naudok YubiKey, kad prisijungtum prie savo paskyros. Veikia su YubiKey 4, 4 Nano, 4C ir NEO įrenginiais." }, - "duoDesc": { - "message": "Patvirtink su Duo Security naudodami Duo Mobile programą, SMS žinutę, telefono skambutį arba U2F saugumo raktą.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "El. paštas" }, - "emailDesc": { - "message": "Patvirtinimo kodai bus atsiųsti el. paštu tau." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Savarankiškai sukurta aplinka" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Patvirtinti failo slaptažodį" }, + "exportSuccess": { + "message": "Eksportuoti saugyklos duomenys" + }, "typePasskey": { "message": "Prieigos raktas" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filtrai" } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 6ddfda8d57b..f75a558f62e 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -50,7 +50,7 @@ "message": "Galvenās paroles norāde var palīdzēt atcerēties paroli, ja tā ir aizmirsta." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Ja tiks aizmirsta parole, tās norādi var nosūtīt uz e-pasta adresi. $CURRENT$/$MAXIMUM$ lielākais pieļaujamais rakstzīmju skaits.", "placeholders": { "current": { "content": "$1", @@ -183,7 +183,7 @@ "message": "Apstiprināšanas kods" }, "confirmIdentity": { - "message": "Jāapstiprina identitāte, lai turpinātu." + "message": "Jāapliecina sava identitāte, lai turpinātu." }, "changeMasterPassword": { "message": "Mainīt galveno paroli" @@ -478,10 +478,10 @@ "message": "Pārlūks neatbalsta vienkāršo ievietošanu starpliktuvē. Tā vietā tas jāievieto starpliktuvē pašrocīgi." }, "verifyIdentity": { - "message": "Apstiprināt identitāti" + "message": "Identitātes apliecināšana" }, "yourVaultIsLocked": { - "message": "Glabātava ir aizslēgta. Jāapstiprina identitāte, lai turpinātu." + "message": "Glabātava ir aizslēgta. Jāapliecina sava identitāte, lai turpinātu." }, "unlock": { "message": "Atslēgt" @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentificētāja lietotne" }, - "authenticatorAppDesc": { - "message": "Izmanto autentificētāja lietotni (piemēram, Authy vai Google autentifikators), lai izveidotu laikā balstītus apstiprinājuma kodus!", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP drošības atslēga" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Ir izmantojams YubiKey, lai piekļūtu savam kontam. Darbojas ar YubiKey 4, 4 Nano, 4C un NEO ierīcēm." }, - "duoDesc": { - "message": "Ar Duo Security apliecināšanu var veikt ar Duo Mobile lietotni, īsziņu, tālruņa zvanu vai U2F drošības atslēgu.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-pasts" }, - "emailDesc": { - "message": "Apstiprinājuma kodi tiks nosūtīti e-pastā." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Pašuzturēta vide" @@ -2159,7 +2159,7 @@ "message": "Galvenās paroles apstiprināšana" }, "passwordConfirmationDesc": { - "message": "Šī darbība ir aizsargāta. Lai turpinātu, ir jāievada galvenā parole, lai apstiprinātu identitāti." + "message": "Šī darbība ir aizsargāta. Lai turpinātu, ir jāievada galvenā parole, lai apliecinātu savu identitāti." }, "emailVerificationRequired": { "message": "Nepieciešama e-pasta adreses apstiprināšana" @@ -2890,7 +2890,7 @@ "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": "Pārslēgt sānu pārvietošanās joslu" }, "skipToContent": { "message": "Pāriet uz saturu" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Apstiprināt datnes paroli" }, + "exportSuccess": { + "message": "Glabātavas saturs izgūts" + }, "typePasskey": { "message": "Piekļuves atslēga" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Atspējotu apvienību vienumiem nevar piekļūt. Jāsazinās ar apvienības īpašnieku, lai iegūtu palīdzību." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Atlases" } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 9f99b4f15ee..b8c37b4e8fa 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "ഓതന്റിക്കേറ്റർ ആപ്പ്" }, - "authenticatorAppDesc": { - "message": "സമയ-അടിസ്ഥാന പരിശോധന കോഡുകൾ സൃഷ്ടിക്കുന്നതിന് ഒരു ഓതന്റിക്കേറ്റർ അപ്ലിക്കേഷൻ (ഓത്തി അല്ലെങ്കിൽ Google ഓതന്റിക്കേറ്റർ പോലുള്ളവ) ഉപയോഗിക്കുക.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP സുരക്ഷാ കീ" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "നിങ്ങളുടെ അക്കൗണ്ട് ആക്സസ് ചെയ്യുന്നതിന് ഒരു യൂബിക്കി ഉപയോഗിക്കുക. YubiKey 4, 4 Nano, 4C, NEO ഉപകരണങ്ങളിൽ പ്രവർത്തിക്കുന്നു." }, - "duoDesc": { - "message": "Duo Mobile അപ്ലിക്കേഷൻ, എസ്എംഎസ്, ഫോൺ കോൾ അല്ലെങ്കിൽ യു 2 എഫ് സുരക്ഷാ കീ ഉപയോഗിച്ച് Duoസെക്യൂരിറ്റി ഉപയോഗിച്ച് പരിശോധിക്കുക.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "ഇമെയിൽ" }, - "emailDesc": { - "message": "സ്ഥിരീകരണ കോഡുകൾ നിങ്ങൾക്ക് ഇമെയിൽ ചെയ്യും." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "സ്വയം ഹോസ്റ്റുചെയ്‌ത എൻവിയോണ്മെന്റ്" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 7916e5cfe1a..8453c94d12b 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index e4fc9c23f01..b091f15db64 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index c6ed8beb6bf..9cdc47c0837 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentiseringsapp" }, - "authenticatorAppDesc": { - "message": "Bruk en autentiseringsapp (f.eks. Authy eller Google Authenticator) for å generere tidsbegrensede verifiseringskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP-sikkerhetsnøkkel" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Bruk en YubiKey for å få tilgang til kontoen din. Virker med enheter av typene YubiKey 4, 4 Nano, 4C, og NEO." }, - "duoDesc": { - "message": "Verifiser med Duo Security gjennom Duo Mobile-appen, SMS, telefonsamtale, eller en U2F-sikkerhetsnøkkel.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Verifiseringskoder vil bli sendt til deg med E-post." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Selvbetjent miljø" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Bekreft filpassord" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index e4fc9c23f01..b091f15db64 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index ddb1313c4ad..50faf826272 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticatie-app" }, - "authenticatorAppDesc": { - "message": "Gebruik een authenticatie-app (zoals Authy of Google Authenticator) om tijdgebaseerde authenticatiecodes te genereren.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Door een authenticatie-app zoals Bitwarden Authenticator gegenereerde code invoeren.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { + "yubiKeyTitleV2": { "message": "YubiKey OTP-beveiligingssleutel" }, "yubiKeyDesc": { "message": "Gebruik een YubiKey om toegang te krijgen tot uw account. Werkt met YubiKey 4, 4 Nano, 4C en Neo-apparaten." }, - "duoDesc": { - "message": "Verificatie met Duo Security middels de Duo Mobile-app, sms, spraakoproep of een U2F-beveiligingssleutel.", + "duoDescV2": { + "message": "Door Duo Security gegenereerde code invoeren.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Je ontvangt verificatiecodes via e-mail." + "emailDescV2": { + "message": "Via e-mail verstuurde code invoeren." }, "selfHostedEnvironment": { "message": "Zelfgehoste omgeving" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Bestandswachtwoord bevestigen" }, + "exportSuccess": { + "message": "Kluisgegevens geëxporteerd" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in een gedeactiveerde organisatie zijn niet toegankelijk. Neem contact op met de eigenaar van je organisatie voor hulp." }, + "upload": { + "message": "Uploaden" + }, + "addAttachment": { + "message": "Bijlage toevoegen" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximale bestandsgrootte is 500 MB" + }, + "deleteAttachmentName": { + "message": "Bijlage $NAME$ verwijderen", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "$NAME$ downloaden", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Weet je zeker dat je deze bijlage definitief permanen wilt verwijderen?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Gratis organisaties kunnen geen bijlagen gebruiken" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index e4fc9c23f01..b091f15db64 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index e4fc9c23f01..b091f15db64 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 60792df2a41..e66f430bc52 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplikacja uwierzytelniająca" }, - "authenticatorAppDesc": { - "message": "Użyj aplikacji mobilnej (np. Authy lub Google Authenticator) do generowania czasowych kodów weryfikacyjnych.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Wprowadź kod wygenerowany przez aplikację uwierzytelniającą, jak Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Klucz bezpieczeństwa YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Klucz bezpieczeństwa Yubico OTP" }, "yubiKeyDesc": { "message": "Użyj YubiKey jako metody dostępu do konta. Działa z YubiKey 4, 4 Nano, 4C i urządzeniami NEO." }, - "duoDesc": { - "message": "Weryfikacja z użyciem Duo Security poprzez aplikację Duo Mobile, SMS, połączenie telefoniczne lub klucz bezpieczeństwa U2F.", + "duoDescV2": { + "message": "Wprowadź kod wygenerowany przez Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Adres e-mail" }, - "emailDesc": { - "message": "Kody weryfikacyjne zostaną wysłane do Ciebie wiadomością e-mail." + "emailDescV2": { + "message": "Wpisz kod wysłany na Twój adres e-mail." }, "selfHostedEnvironment": { "message": "Samodzielnie hostowane środowisko" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Potwierdź hasło pliku" }, + "exportSuccess": { + "message": "Dane sejfu zostały wyeksportowane" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Nie można uzyskać dostępu do elementów w wyłączonych organizacjach. Skontaktuj się z właścicielem organizacji, aby uzyskać pomoc." }, + "upload": { + "message": "Wyślij" + }, + "addAttachment": { + "message": "Dodaj załącznik" + }, + "maxFileSizeSansPunctuation": { + "message": "Maksymalny rozmiar pliku to 500 MB" + }, + "deleteAttachmentName": { + "message": "Usuń załącznik $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Pobierz $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Czy na pewno chcesz trwale usunąć ten załącznik?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Darmowe organizacje nie mogą używać załączników" + }, "filters": { "message": "Filtry" } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 94c1e349bb7..24e660c0f42 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplicativo de Autenticação" }, - "authenticatorAppDesc": { - "message": "Utilize um aplicativo de autenticação (tal como Authy ou Google Authenticator) para gerar códigos de verificação baseados no tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chave de Segurança YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Utilize uma YubiKey para acessar a sua conta. Funciona com YubiKey 4, 4 Nano, 4C, e dispositivos NEO." }, - "duoDesc": { - "message": "Verifique com o Duo Security utilizando o aplicativo Duo Mobile, SMS, chamada telefônica, ou chave de segurança U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Os códigos de verificação vão ser enviados por e-mail para você." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Ambiente Auto-hospedado" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirmar senha do arquivo" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Chave de acesso" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Itens em organizações desativadas não podem ser acessados. Entre em contato com o proprietário da sua organização para obter assistência." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 882f33db0ab..30cf90c557b 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplicação de autenticação" }, - "authenticatorAppDesc": { - "message": "Utilize uma aplicação de autenticação (como o Authy ou o Google Authenticator) para gerar códigos de verificação baseados no tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Introduza um código gerado por uma aplicação de autenticação como o Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chave de segurança YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Chave de segurança Yubico OTP" }, "yubiKeyDesc": { "message": "Utilize uma YubiKey para aceder à sua conta. Funciona com os dispositivos YubiKey 4, 4 Nano, 4C e NEO." }, - "duoDesc": { - "message": "Verifique com a Duo Security utilizando a aplicação Duo Mobile, SMS, chamada telefónica ou chave de segurança U2F.", + "duoDescV2": { + "message": "Introduza um código gerado pelo Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Os códigos de verificação ser-lhe-ão enviados por e-mail." + "emailDescV2": { + "message": "Introduza um código enviado para o seu e-mail." }, "selfHostedEnvironment": { "message": "Ambiente auto-hospedado" @@ -1382,7 +1382,7 @@ "message": "Nome próprio" }, "middleName": { - "message": "Segundo nome" + "message": "Nome do meio" }, "lastName": { "message": "Apelido" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirmar a palavra-passe do ficheiro" }, + "exportSuccess": { + "message": "Dados do cofre exportados" + }, "typePasskey": { "message": "Chave de acesso" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Não é possível aceder aos itens de organizações desativadas. Contacte o proprietário da organização para obter assistência." }, + "upload": { + "message": "Carregar" + }, + "addAttachment": { + "message": "Adicionar anexo" + }, + "maxFileSizeSansPunctuation": { + "message": "O tamanho máximo do ficheiro é de 500 MB" + }, + "deleteAttachmentName": { + "message": "Eliminar o anexo $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Transferir $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Tem a certeza de que pretende eliminar permanentemente este anexo?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "As organizações gratuitas não podem utilizar anexos" + }, "filters": { "message": "Filtros" } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 055592fa093..22ab6d26e22 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplicația Authenticator" }, - "authenticatorAppDesc": { - "message": "Utilizați o aplicație de autentificare (cum ar fi Authy sau Google Authenticator) pentru a genera codurile de verificare bazate pe timp.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Cheie de securitate YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Utilizați YubiKey pentru a accesa contul dvs. Funcționează cu dispozitivele YubiKey 4, 4 Nano, 4C și NEO." }, - "duoDesc": { - "message": "Verificați cu Duo Security utilizând aplicația Duo Mobile, SMS, apel telefonic sau cheia de securitate U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Codurile de verificare vor fi trimise prin e-mail." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Mediu autogăzduit" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index bc9ae9fd7f5..d65bd5d83b3 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Приложение-аутентификатор" }, - "authenticatorAppDesc": { - "message": "Используйте приложение-аутентификатор (например, Authy или Google Authenticator) для создания кодов проверки на основе времени.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ безопасности YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Используйте YubiKey для доступа к вашей учетной записи. Работает с устройствами YubiKey 4 серии, 5 серии и NEO." }, - "duoDesc": { - "message": "Подтвердите с помощью Duo Security, используя приложение Duo Mobile, SMS, телефонный звонок или ключ безопасности U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Коды подтверждения будут отправлены вам по электронной почте." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Окружение пользовательского хостинга" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Подтвердите пароль к файлу" }, + "exportSuccess": { + "message": "Данные хранилища экспортированы" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Доступ к элементам в деактивированных организациях невозможен. Обратитесь за помощью к владельцу организации." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { - "message": "Filters" + "message": "Фильтры" } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 71d56b07f70..4ae72c654fc 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "සත්යාපන යෙදුම" }, - "authenticatorAppDesc": { - "message": "කාලය මත පදනම් වූ සත්යාපන කේත ජනනය කිරීම සඳහා සත්යාපන යෙදුමක් (සත්යාපන හෝ ගූගල් සත්යාපන වැනි) භාවිතා කරන්න.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP ආරක්ෂක යතුර" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "ඔබගේ ගිණුමට ප්රවේශ වීමට YuBiKey භාවිතා කරන්න. YuBiKey 4, 4 නැනෝ, 4C, සහ NEO උපාංග සමඟ ක්රියා කරයි." }, - "duoDesc": { - "message": "Duo ජංගම යෙදුම, කෙටි පණිවුඩ, දුරකථන ඇමතුමක්, හෝ U2F ආරක්ෂක යතුර භාවිතා කරමින් Duo ආරක්ෂක සමඟ තහවුරු කරන්න.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "ඊ-තැපැල්" }, - "emailDesc": { - "message": "සත්යාපන කේත ඔබට විද්යුත් තැපැල් කරනු ඇත." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "ස්වයං සත්කාරක පරිසරය" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 6dcc031bdfb..7705013a707 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Overovacia aplikácia" }, - "authenticatorAppDesc": { - "message": "Použite overovaciu aplikáciu (napríklad Authy alebo Google Authenticator) na generovanie časovo obmedzených overovacích kódov.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Zadajte kód vygenerovaný overovacou aplikáciou akou je Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP bezpečnostný kľúč" + "yubiKeyTitleV2": { + "message": "Bezpečnostný kľúč Yubico OTP" }, "yubiKeyDesc": { "message": "Použiť YubiKey pre prístup k vášmu účtu. Pracuje s YubiKey 4, 4 Nano, 4C a s NEO zariadeniami." }, - "duoDesc": { - "message": "Overiť s Duo Security použitím Duo Mobile aplikácie, SMS, telefonátu alebo U2F bezpečnostným kľúčom.", + "duoDescV2": { + "message": "Zadajte kód vygenerovaný aplikáciou Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verifikačné kódy vám budú zaslané emailom." + "emailDescV2": { + "message": "Zadajte kód zaslaný na váš e-mail." }, "selfHostedEnvironment": { "message": "Sebou hosťované prostredie" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Potvrdiť heslo súboru" }, + "exportSuccess": { + "message": "Údaje z trezora boli exportované" + }, "typePasskey": { "message": "Prístupový kľúč" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "K položkám vo vypnutej organizácii nie je možné pristupovať. Požiadajte o pomoc vlastníka organizácie." }, + "upload": { + "message": "Nahrať" + }, + "addAttachment": { + "message": "Priložiť prílohu" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximálna veľkosť súboru je 500 MB" + }, + "deleteAttachmentName": { + "message": "Odstrániť prílohu $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Stiahnuť $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Naozaj chcete natrvalo odstrániť túto prílohu?" + }, + "premium": { + "message": "Prémium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Bezplatné organizácie nemôžu používať prílohy" + }, "filters": { - "message": "Filters" + "message": "Filtre" } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index e13b1d71727..3925e7a0567 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Aplikacija za avtentikacijo" }, - "authenticatorAppDesc": { - "message": "Uporabite aplikacijo za avtentikacijo (npr. Authy ali Google Authenticator), ki za vas ustvarja časovno spremenljive kode.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Varnostni ključ YubiKey za enkratna gesla" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Za dostop do svojega računa uporabite YubiKey. Podprti so YubiKey 4, 4 Nano, 4C in naprave NEO." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-pošta" }, - "emailDesc": { - "message": "Potrditvene kode vam bodo posredovane po e-pošti." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 9820cea4616..3c94ae83ee9 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Апликација Аутентификатор" }, - "authenticatorAppDesc": { - "message": "Користите апликацију за аутентификацију (као што је Authy или Google Authenticator) за генерисање верификационих кодова.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Унесите кôд који генерише апликација за аутентификацију као што је Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP сигурносни кључ" + "yubiKeyTitleV2": { + "message": "Yubico OTP сигурносни кључ" }, "yubiKeyDesc": { "message": "Користите YubiKey за приступ налогу. Ради са YubiKey 4, 4 Nano, 4C, и NEO уређајима." }, - "duoDesc": { - "message": "Провери са Duo Security користећи Duo Mobile апликацију, СМС, телефонски позив, или U2F кључ.", + "duoDescV2": { + "message": "Унесите кôд који је генерисао Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Е-пошта" }, - "emailDesc": { - "message": "Верификациони кодови ће вам бити послати имејлом." + "emailDescV2": { + "message": "Унесите кôд послат на ваш имејл." }, "selfHostedEnvironment": { "message": "Самостално окружење" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Потврдити лозинку датотеке" }, + "exportSuccess": { + "message": "Подаци из сефа су извезени" + }, "typePasskey": { "message": "Приступачни кључ" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Није могуће приступити ставкама у деактивираним организацијама. Обратите се власнику ваше организације за помоћ." }, + "upload": { + "message": "Отпреми" + }, + "addAttachment": { + "message": "Додај прилог" + }, + "maxFileSizeSansPunctuation": { + "message": "Максимална величина је 500МБ" + }, + "deleteAttachmentName": { + "message": "Обриши прилог $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Преузми $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Да ли сте сигурни да желите да трајно избришете овај прилог?" + }, + "premium": { + "message": "Премијум" + }, + "freeOrgsCannotUseAttachments": { + "message": "Бесплатне организације не могу да користе прилоге" + }, "filters": { - "message": "Filters" + "message": "Филтери" } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 200db544ac9..fcc5ced613d 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Autentiseringsapp" }, - "authenticatorAppDesc": { - "message": "Använd en autentiseringsapp (till exempel Authy eller Google Authenticator) för att skapa tidsbaserade verifieringskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP säkerhetsnyckel" + "yubiKeyTitleV2": { + "message": "Yubico OTP-säkerhetsnyckel" }, "yubiKeyDesc": { "message": "Använd en YubiKey för att få åtkomst till ditt konto. Fungerar med YubiKey 4, 4 Nano, 4C och NEO enheter." }, - "duoDesc": { - "message": "Verifiera med Duo Security genom att använda Duo Mobile-appen, SMS, telefonsamtal eller en U2F säkerhetsnyckel.", + "duoDescV2": { + "message": "Ange en kod som genererats av Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Verifieringskoder kommer att skickas till dig via e-post." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Egen-hostad miljö" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Bekräfta fillösenord" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Lösennyckel" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Ladda upp" + }, + "addAttachment": { + "message": "Lägg till bilaga" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximal filstorlek är 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Ladda ner $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index e4fc9c23f01..b091f15db64 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 3074053619a..89fd0f25731 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Security Key" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "อีเมล" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Self-hosted Environment" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 4b630226b24..01749e6a569 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Kimlik doğrulama uygulaması" }, - "authenticatorAppDesc": { - "message": "Zamana dayalı doğrulama kodları oluşturmak için kimlik doğrulama uygulaması (örn. Authy veya Google Authenticator) kullanın.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP güvenlik anahtarı" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "Hesabınıza erişmek için bir YubiKey kullanın. YubiKey 4, 4 Nano, 4C ve NEO cihazlarıyla çalışır." }, - "duoDesc": { - "message": "Duo Security ile doğrulama için Duo Mobile uygulaması, SMS, telefon araması veya U2F güvenlik anahtarını kullanın.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "E-posta" }, - "emailDesc": { - "message": "Doğrulama kodları e-posta adresinize gönderilecek." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Şirket içinde barındırılan ortam" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Dosya parolasını onaylayın" }, + "exportSuccess": { + "message": "Kasa verileri dışa aktarıldı" + }, "typePasskey": { "message": "Geçiş anahtarı" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Pasif kuruluşlardaki kayıtlara erişilemez. Destek almak için kuruluş sahibinizle iletişime geçin." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filtreler" } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 4621b7a916a..4a19c7bd328 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Програма автентифікації" }, - "authenticatorAppDesc": { - "message": "Використовуйте програму автентифікації (наприклад, Authy або Google Authenticator), щоб генерувати тимчасові коди підтвердження.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Введіть код, згенерований програмою для автентифікації, як-от Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ безпеки YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Ключ безпеки Yubico OTP" }, "yubiKeyDesc": { "message": "Використовуйте YubiKey для доступу до сховища. Працює з YubiKey 4, 4 Nano, 4C та пристроями NEO." }, - "duoDesc": { - "message": "Авторизуйтесь за допомогою Duo Security з використанням мобільного додатку Duo Mobile, SMS, телефонного виклику, або ключа безпеки U2F.", + "duoDescV2": { + "message": "Введіть код, згенерований Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Е-пошта" }, - "emailDesc": { - "message": "Коди підтвердження будуть надсилатися на вашу пошту." + "emailDescV2": { + "message": "Введіть код, надісланий вам електронною поштою." }, "selfHostedEnvironment": { "message": "Середовище власного хостингу" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Підтвердьте пароль файлу" }, + "exportSuccess": { + "message": "Дані сховища експортовано" + }, "typePasskey": { "message": "Ключ доступу" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "Елементи в деактивованих організаціях недоступні. Зверніться до власника вашої організації для отримання допомоги." }, + "upload": { + "message": "Вивантажити" + }, + "addAttachment": { + "message": "Додати вкладення" + }, + "maxFileSizeSansPunctuation": { + "message": "Максимальний розмір файлу – 500 МБ" + }, + "deleteAttachmentName": { + "message": "Видалити вкладення $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Завантажити $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Ви дійсно хочете остаточно видалити це вкладення?" + }, + "premium": { + "message": "Преміум" + }, + "freeOrgsCannotUseAttachments": { + "message": "Організації без передплати не можуть використовувати вкладення" + }, "filters": { - "message": "Filters" + "message": "Фільтри" } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 2af7d82f8d1..15874347b44 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "Ứng dụng Authenticator" }, - "authenticatorAppDesc": { - "message": "Sử dụng một ứng dụng xác thực (chẳng hạn như Authy hoặc Google Authenticator) để tạo các mã xác nhận theo thời gian thực.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Khóa bảo mật YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "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." }, - "duoDesc": { - "message": "Xác minh với Duo Security bằng ứng dụng Duo Mobile, SMS, cuộc gọi điện thoại, hoặc khoá bảo mật U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Mã xác thực sẽ được gửi qua email cho bạn." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "Môi trường tự lưu trữ" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "Confirm file password" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "Passkey" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 0706fb85f14..d2d8f6d7dbc 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -20,7 +20,7 @@ "message": "设置强密码" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "设置密码后就能完成账户创建" + "message": "设置密码以完成账户的创建" }, "login": { "message": "登录" @@ -50,7 +50,7 @@ "message": "主密码提示可以在您忘记密码时帮您回忆起来。" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "如果您忘记了密码,可以发送密码提示到您的电子邮箱。$CURRENT$ / 最多 $MAXIMUM$ 个字符。", "placeholders": { "current": { "content": "$1", @@ -1013,7 +1013,7 @@ "message": "感谢您支持 Bitwarden。" }, "premiumPrice": { - "message": "每年只需 $PRICE$ !", + "message": "只需 $PRICE$ /年!", "placeholders": { "price": { "content": "$1", @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "验证器 App" }, - "authenticatorAppDesc": { - "message": "使用验证器 App(例如 Authy 或 Google Authenticator)来生成基于时间的验证码。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 安全钥匙" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "使用 YubiKey 来访问您的账户。支持 YubiKey 4、4 Nano、4C 以及 NEO 设备。" }, - "duoDesc": { - "message": "使用 Duo Security 的 Duo 移动应用、短信、电话或 U2F 安全钥匙来进行验证。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "电子邮件" }, - "emailDesc": { - "message": "验证码将会发送到您的电子邮箱。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "自托管环境" @@ -2890,7 +2890,7 @@ "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": "切换侧边导航" }, "skipToContent": { "message": "跳转到正文" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "确认文件密码" }, + "exportSuccess": { + "message": "密码库数据已导出" + }, "typePasskey": { "message": "通行密钥" }, @@ -3495,7 +3498,43 @@ "contactYourOrgAdmin": { "message": "无法访问已停用组织中的项目。请联系您的组织所有者获取协助。" }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { - "message": "Filters" + "message": "筛选" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 749e5fe7c25..2f2ab757e52 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -1105,18 +1105,18 @@ "authenticatorAppTitle": { "message": "驗證器應用程式" }, - "authenticatorAppDesc": { - "message": "使用驗證器應用程式 (如 Authy 或 Google Authenticator) 產生基於時間的驗證碼。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 安全鑰匙" + "yubiKeyTitleV2": { + "message": "Yubico OTP Security Key" }, "yubiKeyDesc": { "message": "使用 YubiKey 存取您的帳戶。支援 YubiKey 4、4 Nano、4C、以及 NEO 裝置。" }, - "duoDesc": { - "message": "使用 Duo Security 的 Duo Mobile 程式、SMS 、撥打電話或 U2F 安全鑰匙進行驗證。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -1132,8 +1132,8 @@ "emailTitle": { "message": "電子郵件" }, - "emailDesc": { - "message": "使用電子郵件傳送驗證碼給您。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "selfHostedEnvironment": { "message": "自我裝載環境" @@ -3107,6 +3107,9 @@ "confirmFilePassword": { "message": "確認檔案密碼" }, + "exportSuccess": { + "message": "Vault data exported" + }, "typePasskey": { "message": "密碼金鑰" }, @@ -3495,6 +3498,42 @@ "contactYourOrgAdmin": { "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." }, + "upload": { + "message": "Upload" + }, + "addAttachment": { + "message": "Add attachment" + }, + "maxFileSizeSansPunctuation": { + "message": "Maximum file size is 500 MB" + }, + "deleteAttachmentName": { + "message": "Delete attachment $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "downloadAttachmentName": { + "message": "Download $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "Attachment Name" + } + } + }, + "permanentlyDeleteAttachmentConfirmation": { + "message": "Are you sure you want to permanently delete this attachment?" + }, + "premium": { + "message": "Premium" + }, + "freeOrgsCannotUseAttachments": { + "message": "Free organizations cannot use attachments" + }, "filters": { "message": "Filters" } diff --git a/apps/browser/store/locales/lv/copy.resx b/apps/browser/store/locales/lv/copy.resx index 6d75e8ff0ef..b45743f2e4c 100644 --- a/apps/browser/store/locales/lv/copy.resx +++ b/apps/browser/store/locales/lv/copy.resx @@ -124,48 +124,48 @@ Bitwarden viegli aizsargā visas paroles, paroļu atslēgas un jutīgu informāciju mājās, darbā vai ceļā. - Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! + PCMag, WIRED, The Verge, CNET, G2 un vēl ir atzinuši Bitwarden kā labāko paroļu pārvaldnieku. -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. +AIZSARGĀ SAVU DIGITĀLO DZĪVI +Aizsargā savu digitālo dzīvi un nodrošinies pret datu noplūdēm ar vienreizēju, spēcīgu paruļu izveidošanu un saglabāšanu katram kontam! Glabā visu pilnīgi šifrētā paroļu glabātavā, kurai vari piekļūt vienīgi Tu! -ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE -Easily manage, store, secure, and share unlimited passwords across unlimited devices without restrictions. +PIEKĻŪSTI SAVIEM DATIEM JEBKUR, JEBKAD UN JEBKURĀ IERĪCĒ +Viegla paroļu pārvaldīšana, glabāšana, nodrošināšana un kopīgošana bez ierobežojumiem dažādās ierīcēs. -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. +IKVIENAM VAJADZĒTU IZMANTOT RĪKUS, LAI TIEŠSAISTĒ BŪTU DROŠI +Bitwarden ir izmantojams bez maksas, reklāmām un datu pārdošanas. Bitwarden tic, ka ikvienam vajadzētu būt iespējai būt drošam tiešsaistē. Premium plāni sniedz piekļuvi papildu iespējām. -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. +SPĒCINI SAVAS KOMANDAS AR BITWARDEN +Komandu un uzņēmumu plāni satur profesionālas uzņēmējdarbības iespējas. Piemēram, SSO iekļaušana, pašmitināšana, direktorijas iekļaušana un SCIM apgāde, visaptveroši nosacījumi, API piekļuve, notikumu žurnāli un vēl. -Use Bitwarden to secure your workforce and share sensitive information with colleagues. +Izmanto bitwarden, lai drošinātu savu darbaspēku un kopīgotu jutīgu informāciju ar darbabiedriem! -More reasons to choose Bitwarden: +Vairāk iemelsu, lai izvēlētos Bitwarden: -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. +Pasaules klases šifrēšana +Paroles ir aizsargātas ar sarežģītu pilnīgu šifrēšanu (AES-256 bitu, sālīts jaucējkods un PBKDF2 SHA-256), līdz ar to Tavi dati ir droši un privāti. -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. +Trešo pušu pārbaudes +Bitwarden pastāvīgi veic aptverošas trešo pušu drošības pārbaudes ar atzīstamiem drošības uzņēmumiem. Šīs ikgadējās pārbaudes iekļauj pirmkoda izvērtēšanu un ielaušanās pārbaudes dažādās Bitwarden IP adresēs, serveros un tīmekļa lietotnēs. -Advanced 2FA -Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. +Papildu 2FA +Aizsargā savu pieteikšanos ar trešo pušu autentificētāju, e-pastā nosūtītiem kodiem vai tādiem FIDO2 WebAuthn pieteikšanās datiem kā aparatūras drošības atslēgu vai piekļuves atslēgu! Bitwarden Send -Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. +Datu pārsūtīšana citiem, saglabājot pilnīgu šifrēšanas drošību un ierobežojot atklāšanu. -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. +Iebūvēts veidotājs +Izveido garas, sarežģītas un atšķirīgas paroles un vienreizējus lietotājvārdus katrai apmeklētajai vietnei! Papildu privātumam var apvienot ar e-pasta aizstājvārdu nodrošinātājiem. -Global Translations -Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. +Vispasaules tulkojumi +Bitwarden ir tulkots vairāk nekā 60 valodās ar vispasaules kopienas palīdzību tulkošanas rīkā Crowdin. -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Starpplatformu lietotnes +Aizsargā un kopīgo jutīgus datus savā Bitwarden glabātavā jebkurā pārlūkā, mobilajā ierīcē vai darbvirsmas operētājsistēmā un vēl! -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 aizsargā vairāk nekā tikai paroles +Pilnīgas šifrēšanas pieteikšanās datu pārvaldības risinājumi no Bitwarden sniedz iespēju apvienībām aizsargāt visu, tajā skaitā izstrādātāju noslēpumus un piekļuves atslēgu pieredzes. Bitwarden.com ir ampeklējams, lai uzzinātu vairāk par Bitwarden noslēpumu pārvaldnieku un Bitwarden Passwordless.dev. From 20a6552621094c1bba40486049559e45a5c0fd4b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:12:42 +0000 Subject: [PATCH 033/130] Autosync the updated translations (#9865) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 106 +++++++++----- apps/web/src/locales/ar/messages.json | 114 ++++++++++----- apps/web/src/locales/az/messages.json | 136 +++++++++++------- apps/web/src/locales/be/messages.json | 106 +++++++++----- apps/web/src/locales/bg/messages.json | 116 +++++++++++----- apps/web/src/locales/bn/messages.json | 112 ++++++++++----- apps/web/src/locales/bs/messages.json | 114 ++++++++++----- apps/web/src/locales/ca/messages.json | 104 +++++++++----- apps/web/src/locales/cs/messages.json | 108 ++++++++++----- apps/web/src/locales/cy/messages.json | 114 ++++++++++----- apps/web/src/locales/da/messages.json | 120 ++++++++++------ apps/web/src/locales/de/messages.json | 116 +++++++++++----- apps/web/src/locales/el/messages.json | 106 +++++++++----- apps/web/src/locales/en_GB/messages.json | 106 +++++++++----- apps/web/src/locales/en_IN/messages.json | 106 +++++++++----- apps/web/src/locales/eo/messages.json | 108 ++++++++++----- apps/web/src/locales/es/messages.json | 106 +++++++++----- apps/web/src/locales/et/messages.json | 106 +++++++++----- apps/web/src/locales/eu/messages.json | 106 +++++++++----- apps/web/src/locales/fa/messages.json | 106 +++++++++----- apps/web/src/locales/fi/messages.json | 168 ++++++++++++++--------- apps/web/src/locales/fil/messages.json | 106 +++++++++----- apps/web/src/locales/fr/messages.json | 120 ++++++++++------ apps/web/src/locales/gl/messages.json | 114 ++++++++++----- apps/web/src/locales/he/messages.json | 110 ++++++++++----- apps/web/src/locales/hi/messages.json | 114 ++++++++++----- apps/web/src/locales/hr/messages.json | 106 +++++++++----- apps/web/src/locales/hu/messages.json | 116 +++++++++++----- apps/web/src/locales/id/messages.json | 106 +++++++++----- apps/web/src/locales/it/messages.json | 104 +++++++++----- apps/web/src/locales/ja/messages.json | 136 +++++++++++------- apps/web/src/locales/ka/messages.json | 106 +++++++++----- apps/web/src/locales/km/messages.json | 114 ++++++++++----- apps/web/src/locales/kn/messages.json | 106 +++++++++----- apps/web/src/locales/ko/messages.json | 106 +++++++++----- apps/web/src/locales/lv/messages.json | 122 ++++++++++------ apps/web/src/locales/ml/messages.json | 110 ++++++++++----- apps/web/src/locales/mr/messages.json | 114 ++++++++++----- apps/web/src/locales/my/messages.json | 114 ++++++++++----- apps/web/src/locales/nb/messages.json | 106 +++++++++----- apps/web/src/locales/ne/messages.json | 114 ++++++++++----- apps/web/src/locales/nl/messages.json | 102 ++++++++++---- apps/web/src/locales/nn/messages.json | 114 ++++++++++----- apps/web/src/locales/or/messages.json | 114 ++++++++++----- apps/web/src/locales/pl/messages.json | 110 ++++++++++----- apps/web/src/locales/pt_BR/messages.json | 104 +++++++++----- apps/web/src/locales/pt_PT/messages.json | 128 +++++++++++------ apps/web/src/locales/ro/messages.json | 106 +++++++++----- apps/web/src/locales/ru/messages.json | 106 +++++++++----- apps/web/src/locales/si/messages.json | 114 ++++++++++----- apps/web/src/locales/sk/messages.json | 116 +++++++++++----- apps/web/src/locales/sl/messages.json | 106 +++++++++----- apps/web/src/locales/sr/messages.json | 118 +++++++++++----- apps/web/src/locales/sr_CS/messages.json | 114 ++++++++++----- apps/web/src/locales/sv/messages.json | 106 +++++++++----- apps/web/src/locales/te/messages.json | 114 ++++++++++----- apps/web/src/locales/th/messages.json | 114 ++++++++++----- apps/web/src/locales/tr/messages.json | 106 +++++++++----- apps/web/src/locales/uk/messages.json | 124 +++++++++++------ apps/web/src/locales/vi/messages.json | 108 ++++++++++----- apps/web/src/locales/zh_CN/messages.json | 150 ++++++++++++-------- apps/web/src/locales/zh_TW/messages.json | 104 +++++++++----- 62 files changed, 4805 insertions(+), 2201 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index ad0d495cc6e..f168ffeffd4 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Waarmerktoep" }, - "authenticatorAppDesc": { - "message": "Gebruik ’n waarmerktoep (soos Authy of Google Authenticator) om tydgebaseerde bevestigingskodes te genereer.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey-OTP-beveiligingsleutel" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Gebruik ’n YubiKey vir toegang tot u rekening. Werk met YubiKey reeks 4, reeks 5 en NEO-toestelle." }, - "duoDesc": { - "message": "Bevestig met Duo Security d.m.v. die Duo Mobile-toep, SMS, spraakoproep of ’n U2F-beveiligingsleutel.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-pos" }, - "emailDesc": { - "message": "U sal bevestigingskodes per e-pos ontvang." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Gaan voort" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Voer u hoofwagwoord in om tweestapaantekeninstellings te wysig." }, - "twoStepAuthenticatorDesc": { - "message": "Volg hierdie stappe om tweestapaantekening met ’n waarmerktoep op te stel:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Laai ’n tweestapwaarmerktoep af" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Kort u ’n tweestapwaarmerktoep? Laai een van die volgende af" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS-toestelle" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-toestelle" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-toestelle" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Hierdie toeps word aanbeveel, maar ander waarmerktoeps sal ook werk." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skandeer hierdie QR-kode met u waarmerktoep" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Sleutel" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Alle Spanne-funksies, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 6c722a842cd..ba2cdf9af66 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "تطبيق المصادقة" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "البريد الإلكتروني" }, - "emailDesc": { - "message": "سيتم إرسال رمز التحقق إليك بالبريد الإلكتروني." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "استمرار" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "أجهزة iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "أجهزة الأندرويد" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "أجهزة ويندوز" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 702912c0dba..996a443f8e6 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -37,7 +37,7 @@ "message": "Notlar" }, "customFields": { - "message": "Özəl sahələr" + "message": "Özəl xanalar" }, "cardholderName": { "message": "Kart sahibinin adı" @@ -142,7 +142,7 @@ "message": "Qovluq" }, "newCustomField": { - "message": "Yeni özəl sahə" + "message": "Yeni özəl xana" }, "value": { "message": "Dəyər" @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Kimlik doğrulayıcı tətbiqi" }, - "authenticatorAppDesc": { - "message": "Vaxt əsaslı doğrulama kodları yaratmaq üçün (Authy və ya Google Authenticator kimi) kimlik doğrulayıcı tətbiq istifadə edin.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP güvənlik açarı" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Hesabınıza müraciət etmək üçün bir YubiKey istifadə edin. YubiKey 4 seriyası, 5 seriyası və NEO cihazları ilə işləyir." }, - "duoDesc": { - "message": "Duo Security ilə doğrulamaq üçün Duo Mobile tətbiqi, SMS, telefon zəngi və ya U2F güvənlik açarını istifadə edin.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-poçt" }, - "emailDesc": { - "message": "Doğrulama kodları e-poçt ünvanınıza göndəriləcək." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Davam" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "İki addımlı giriş ayarlarını dəyişdirmək üçün ana parolunuzu daxil edin." }, - "twoStepAuthenticatorDesc": { - "message": "Kimlik doğrulayıcı tətbiqi ilə iki addımlı girişi qurmaq üçün aşağıdakı addımları izləyin:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "İki addımlı kimlik doğrulayıcı tətbiqi endirin" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "İki addımlı kimlik doğrulayıcı tətbiqi lazımdır? Aşağıdakılardan birini endirin" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS cihazları" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android cihazları" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows cihazları" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Bu tətbiqləri tövsiyə edirik, ancaq digər kimlik doğrulayıcı tətbiqlərini də işlədə bilərsiniz." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Bu QR kodunu kimlik doğrulayıcı tətbiqinizlə skan edin" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Açar" }, - "twoStepAuthenticatorEnterCode": { - "message": "Tətbiqdəki 6 rəqəmli doğrulama kodunu daxil edin" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Başqa bir cihaza əlavə etmək lazım olsa, aşağıda kimlik doğrulayıcı tətbiqinizin tələb etdiyi QR kod (və ya açar) verilib." @@ -1685,7 +1694,7 @@ "message": "\"YubiKey\"i kompüterinizin USB portuna taxın." }, "twoFactorYubikeySelectKey": { - "message": "Aşağıdakı ilk boş YubiKey giriş sahəsini seçin." + "message": "Aşağıdakı ilk boş YubiKey giriş xanasını seçin." }, "twoFactorYubikeyTouchButton": { "message": "\"YubiKey\"in düyməsinə toxunun." @@ -2751,7 +2760,7 @@ "message": "Üzvə düzəliş et" }, "fieldOnTabRequiresAttention": { - "message": "\"$TAB$\" vərəqindəki bir sahə diqqətinizi tələb edir.", + "message": "\"$TAB$\" vərəqindəki bir xana diqqətinizi tələb edir.", "placeholders": { "tab": { "content": "$1", @@ -2961,7 +2970,7 @@ } }, "viewedHiddenFieldItemId": { - "message": "$ID$ elementi üçün gizli sahəyə baxıldı.", + "message": "$ID$ elementi üçün gizli xanaya baxıldı.", "placeholders": { "id": { "content": "$1", @@ -3015,7 +3024,7 @@ } }, "copiedHiddenFieldItemId": { - "message": "$ID$ elementi üçün gizli sahə kopyalandı.", + "message": "$ID$ elementi üçün gizli xana kopyalandı.", "placeholders": { "id": { "content": "$1", @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Bu pəncərə 5 saniyəyə avtomatik bağlanacaq" }, + "youMayCloseThisWindow": { + "message": "Bu pəncərəni bağlaya bilərsiniz" + }, "includeAllTeamsFeatures": { "message": "Bütün komanda özəllikləri, əlavə olaraq:" }, @@ -5687,7 +5699,7 @@ "message": "Tələb edildi" }, "formErrorSummaryPlural": { - "message": "Yuxarıdakı $COUNT$ sahənin diqqətinizə ehtiyacı var.", + "message": "Yuxarıdakı $COUNT$ xananın diqqətinizə ehtiyacı var.", "placeholders": { "count": { "content": "$1", @@ -5696,7 +5708,7 @@ } }, "formErrorSummarySingle": { - "message": "Yuxarıdakı 1 sahənin diqqətinizə ehtiyacı var." + "message": "Yuxarıdakı 1 xananın diqqətinizə ehtiyacı var." }, "fieldRequiredError": { "message": "$FIELDNAME$ tələb olunur.", @@ -6159,7 +6171,7 @@ } }, "fieldsNeedAttention": { - "message": "Yuxarıdakı $COUNT$ sahənin diqqətinizə ehtiyacı var.", + "message": "Yuxarıdakı $COUNT$ xananın diqqətinizə ehtiyacı var.", "placeholders": { "count": { "content": "$1", @@ -6743,7 +6755,7 @@ "message": "Domen yoxdur" }, "noDomainsSubText": { - "message": "Bir domenin bağlantı qurması, üzvlərin SSO ilə Giriş etməsi əsnasında SSO identifikatorunu ötürməsinə icazə verir." + "message": "Bir domenin bağlantı qurması, üzvlərin SSO ilə Giriş etməsi zamanı SSO identifikatoru xanasını ötürməsinə icazə verir." }, "verifyDomain": { "message": "Domeni doğrula" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Müştəri hesabatını xaricə köçür" }, - "invoiceNumberHeader": { - "message": "Faktura nömrəsi", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Üzv müraciəti" }, @@ -8431,21 +8439,55 @@ "message": " Abunəliyinizi bərpa etmək üçün Müştəri Dəstəyi ilə əlaqə saxlayın." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Qrupların və ya insanların bu sirrə müraciətinə icazə verin. İnsanlar üçün təyin edilən icazələr, qruplar tərəfindən təyin edilən icazələri yararsız edəcək." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Bu sirrə müraciəti paylaşmaq üçün insanları və ya qrupları əlavə edin" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Maşın hesablarının bu sirrə müraciətinə icazə verin." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Bu sirrə müraciət icazəsi vermək üçün maşın hesabları əlavə et" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Bu sirrə müraciəti sil" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Bu əməliyyat, bu sirrə olan müraciətinizi götürəcək." + }, + "invoice": { + "message": "Faktura" + }, + "unassignedSeatsAvailable": { + "message": "$SEATS$ təyin edilməmiş yeriniz var.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Əlavə yer satın almaq üçün provayderinizin admini ilə əlaqə saxlayın." + }, + "open": { + "message": "Aç", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Yığıla bilməyən", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index c5fd659abd0..d48a87325fa 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Праграма аўтэнтыфікацыі" }, - "authenticatorAppDesc": { - "message": "Выкарыстоўвайце праграму праграму аўтэнтыфікацыі (напрыклад, Authy або Google Authenticator) для генерацыі праверачных кодаў на падставе часу.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ бяспекі YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Выкарыстоўвайце YubiKey для доступу да вашага ўліковага запісу. Працуе з прыладамі YubiKey серый 4, 5 і NEO." }, - "duoDesc": { - "message": "Праверка з дапамогай Duo Security, выкарыстоўваючы праграму Duo Mobile, SMS, тэлефонны выклік або ключ бяспекі U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Электронная пошта" }, - "emailDesc": { - "message": "Праверачныя коды будуць адпраўляцца вам па электронную пошту." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Працягнуць" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Увядзіце асноўны пароль для змянення наладаў двухэтапнага ўваходу." }, - "twoStepAuthenticatorDesc": { - "message": "Прытрымлівайцеся гэтых крокаў, каб прызначыць двухэтапны ўваход з дапамогай праграмы аўтэнтыфікацыі:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Спампаваць праграму двухэтапнай аўтэнтыфікацыі" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Неабходна праграма двухэтапнай аўтэнтыфікацыі? Спампуйце адну з наступных" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Прылады на iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Прылады на Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Прылады на Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Гэтыя праграмы з'яўляюцца рэкамендаванымі. Звярніце ўвагу, што іншыя праграмы таксама будуць працаваць." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Адскануйце гэты QR-код з дапамогай праграмы аўтэнтыфікацыі" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Ключ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Увядзіце атрыманыя 6 лічбаў праверачнага кода з праграмы" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "У выпадку, калі вам неабходна дадаць іншую прыладу, ніжэй пазначаны QR-код (або ключы), якія патрабуюцца праграме аўтэнтыфікацыі." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Усе функцыі каманд, плюс:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 8610b6cd499..1ab3a95215e 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Приложение за удостоверяване" }, - "authenticatorAppDesc": { - "message": "Използвайте приложение за удостоверяване (като Authy или Google Authenticator) за генерирането на временни кодове за потвърждение.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Устройство YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Използвайте устройство на YubiKey, за да влезете в абонамента си. Поддържат се моделите YubiKey 4, 4 Nano, 4C и NEO." }, - "duoDesc": { - "message": "Удостоверяване чрез Duo Security, с ползване на приложението Duo Mobile, SMS, телефонен разговор или устройство U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Електронна поща" }, - "emailDesc": { - "message": "Кодовете за потвърждение ще ви бъдат пратени по електронна поща." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Продължаване" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Въведете главната си парола, за да променяте настройките за двустепенно удостоверяване." }, - "twoStepAuthenticatorDesc": { - "message": "Следвайте тези стъпки, за да настроите двустепенно удостоверяване:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Изтегляне на приложение за двустепенно удостоверяване" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Ако ви трябва приложение за двустепенно удостоверяване, пробвайте някое от следните:" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Устройства с iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Устройства с Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Устройства с Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Това са само препоръчаните приложения. Другите приложения за идентификация също ще работят." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Сканирайте този QR код с приложението си за идентификация" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Ключ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Въведете 6-цифрения код за потвърждение от приложението" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Ако трябва да добавите и друго устройство, по-долу е QR кодът или ключът, изисквани от приложението ви за идентификация." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Този прозорец ще се затвори автоматично след 5 секунди" }, + "youMayCloseThisWindow": { + "message": "Може да затворите този прозорец" + }, "includeAllTeamsFeatures": { "message": "Всички възможности на Екипния план, плюс:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Изнасяне на клиентската справка" }, - "invoiceNumberHeader": { - "message": "Номер на фактура", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Достъп на членовете" }, @@ -8431,21 +8439,55 @@ "message": " Свържете се с поддръжката, за да възобновите абонамента си." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Дайте достъп на групи или отделни хора до тази тайна. Правата дадени на отделни хора ще имат превес на тези дадени им от групите." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Добавете хора или групи, с които да споделите достъпа до тази тайна" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Дайте достъп на машинните акаунти до тази тайна." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Добавете машинни акаунти, за да дадете достъп до тази тайна" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Премахване на достъпа до тази тайна" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Това действие ще премахне достъпа Ви до тази тайна." + }, + "invoice": { + "message": "Фактура" + }, + "unassignedSeatsAvailable": { + "message": "Имате $SEATS$ неразпределени места.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Свържете се с администратора на доставчика си, за да закупи допълнителни места." + }, + "open": { + "message": "Отваряне", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Плащането не може да бъде получено", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Подробности за клиента" + }, + "downloadCSV": { + "message": "Сваляне на CSV" + }, + "billingHistoryDescription": { + "message": "Свалете файл CSV с подробна информация за клиента и всяка платежна дата. Частичните плащания може да не са включени във файла и да се различават с данните във фактурата. Най-точната информация относно плащанията може да бъде намерена в месечните фактури.", + "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." } } diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index 4a496f1bf8e..a2e29ac625d 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "প্রমাণীকরণকারী অ্যাপ" }, - "authenticatorAppDesc": { - "message": "সময় ভিত্তিক যাচাইকরণ কোড উৎপন্ন করতে একটি প্রমাণীকরণকারী অ্যাপ্লিকেশন (যেমন Authy বা Google Authenticator) ব্যবহার করুন।", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP সুরক্ষা কী" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Duo Mobile app, এসএমএস, ফোন কল, বা U2F সুরক্ষা কী ব্যবহার করে Duo Security এর মাধ্যমে যাচাই করুন।", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -987,10 +987,10 @@ "message": "FIDO U2F সুরক্ষা কী" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index b3fc19441ad..69ca61608f6 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 8a7229e1251..7f6c4c4dfc8 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplicació autenticadora" }, - "authenticatorAppDesc": { - "message": "Utilitzeu una aplicació autenticadora (com Authy o Google Authenticator) per generar codis de verificació basats en el temps.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Clau de seguretat OTP de YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utilitzeu una YubiKey per accedir al vostre compte. Funciona amb els dispositius YubiKey 4, 4 Nano, 4C i NEO." }, - "duoDesc": { - "message": "Verifiqueu amb Duo Security mitjançant l'aplicació Duo Mobile, SMS, trucada telefònica o clau de seguretat U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Correu electrònic" }, - "emailDesc": { - "message": "Els codis de verificació els rebreu per correu electrònic." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continua" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Introduïu la vostra contrasenya mestra per modificar la configuració d'inici de sessió en dues passes." }, - "twoStepAuthenticatorDesc": { - "message": "Seguiu aquestes passes per configurar l'inici de sessió en dues passes amb una aplicació autenticadora:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Baixeu una aplicació autenticadora en dues passes" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Necessiteu una aplicació d'autenticació en dues passes? Baixeu-ne una de les següents" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Dispositius iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Dispositius Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Dispositius Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Es recomanen aquestes aplicacions, però, altres aplicacions autenticadores també funcionaran." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Escanegeu aquest codi QR amb l'aplicació autenticadora" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Clau" }, - "twoStepAuthenticatorEnterCode": { - "message": "Introduïu el codi de verificació de 6 dígits generat a l'aplicació" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "En cas que hàgeu d'afegir-lo a un altre dispositiu, a continuació teniu el codi QR (o clau) requerit per l'aplicació autenticadora." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Aquesta finestra es tancarà automàticament en 5 segons" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Característiques de tots els equips, a més de:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index c50a3c11a78..e951d9c0fd9 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Ověřovací aplikace" }, - "authenticatorAppDesc": { - "message": "Použijte ověřovací aplikaci (jako je Authy nebo Google Authenticator) pro generování časově omezených kódů.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Zadejte kód vygenerovaný ověřovací aplikací, jako je Autentikátor Bitwarden.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { + "yubiKeyTitleV2": { "message": "Bezpečnostní klíč YubiKey OTP" }, "yubiKeyDesc": { "message": "Použije YubiKey pro přístup k Vašemu trezoru. Podporuje YubiKey 4, 5 a NEO." }, - "duoDesc": { - "message": "Ověření pomocí Duo Security prostřednictvím aplikace Duo Mobile, SMS, telefonního hovoru nebo bezpečnostního klíče U2F.", + "duoDescV2": { + "message": "Zadejte kód vygenerovaný DUO Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -987,10 +987,10 @@ "message": "Bezpečnostní klíč FIDO U2F" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Přístupový klíč" }, "webAuthnDesc": { - "message": "Použije jakýkoli bezpečnostní klíč WebAuthn pro přístup k Vašemu účtu." + "message": "Používejte biometrické prvky Vašeho zařízení nebo bezpečnostní klíč kompatibilní s FIDO2." }, "webAuthnMigrated": { "message": "(Migrováno z FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Ověřovací kódy Vám budou zaslány e-mailem." + "emailDescV2": { + "message": "Zadejte kód odeslaný na Váš e-mail." }, "continue": { "message": "Pokračovat" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Zadejte hlavní heslo pro úpravu dvoufázového přihlášení." }, - "twoStepAuthenticatorDesc": { - "message": "Pro nastavení dvoufázového přihlášení pomocí ověřovací aplikace postupujte podle následujících kroků:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Stáhnout ověřovací aplikaci, jako je" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Stáhněte si ověřovací aplikaci" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Potřebujete aplikaci pro dvoufázové ověření? Stáhněte si jednu z následujících:" + "twoStepAuthenticatorInstructionInfix2": { + "message": "nebo" }, - "iosDevices": { - "message": "iOS zařízení" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android zařízení" + "continueToExternalUrlTitle": { + "message": "Pokračovat na $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows zařízení" + "continueToExternalUrlDesc": { + "message": "Opouštíte Bitwarden a spouštíte externí webové stránky v novém okně." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Tyto aplikace doporučujeme, nicméně další aplikace pro ověření budou fungovat také." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Pokračovat na bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Naskenujte tento QR kód Vaší ověřovací aplikací" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Autentikátor Bitwarden umožňuje ukládat ověřovací klíče a generovat TOTP kódy pro 2-fázové ověřování. Další informace naleznete na stránkách bitwarden.com" + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Naskenujte QR kód pomocí Vaší ověřovací aplikace nebo zadejte klíč." }, "key": { "message": "Klíč" }, - "twoStepAuthenticatorEnterCode": { - "message": "Zadejte 6místný kód z ověřovací aplikace" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Ověřovací kód" }, "twoStepAuthenticatorReaddDesc": { "message": "V případě potřeby přidání do jiného zařízení je níže zobrazen QR kód (nebo klíč) vyžadovaný ověřovací aplikací." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Toto okno se automaticky zavře za 5 sekund" }, + "youMayCloseThisWindow": { + "message": "Toto okno můžete zavřít" + }, "includeAllTeamsFeatures": { "message": "Všechny funkce týmů, navíc:" }, @@ -7889,7 +7901,7 @@ "message": "Nastavení uživatelů bude započítáno v dalším fakturačním cyklu." }, "unassignedSeatsDescription": { - "message": "Nepřiřazení uživatelé k odběru" + "message": "Nepřiřazení uživatelé" }, "purchaseSeatDescription": { "message": "Další zakoupení uživatelé" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Exportovat hlášení klienta" }, - "invoiceNumberHeader": { - "message": "Číslo faktury", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Přístup členů" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "Tato akce odebere Váš přístup k tomuto tajnému klíči." + }, + "invoice": { + "message": "Faktura" + }, + "unassignedSeatsAvailable": { + "message": "Máte $SEATS$ uživatelů k dispozici.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Obraťte se na správce svého poskytovatele pro nákup dalších uživatelů." + }, + "open": { + "message": "Otevřít", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Nedobytné", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Detaily klienta" + }, + "downloadCSV": { + "message": "Stáhnout CSV" + }, + "billingHistoryDescription": { + "message": "Stáhněte si soubor CSV a získejte údaje o klientovi pro každé datum fakturace. Proporcionální poplatky nejsou v CSV zahrnuty a mohou se lišit od propojené faktury. Nejpřesnější údaje o vyúčtování naleznete v měsíčních fakturách.", + "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." } } diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index 9ac14fd264f..64f36a316c1 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index 5b15b9d7512..ce8331161b3 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Godkendelses-app" }, - "authenticatorAppDesc": { - "message": "Benyt en godkendelses-app (såsom Authy eller Google Authenticator) til at generere tidsbaserede bekræftelseskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Angiv en kode genereret af en godkendelses-app såsom Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP-sikkerhedsnøgle" + "yubiKeyTitleV2": { + "message": "Yubico OTP-sikkerhedsnøgle" }, "yubiKeyDesc": { - "message": "Benyt en YubiKey for at tilgå din konto. Fungerer med YubiKey 4- og 5-serien samt NEO-enheder." + "message": "Benyt en YubiKey for at tilgå din konto. Fungerer med YubiKey 4-/5-serien samt NEO-enheder." }, - "duoDesc": { - "message": "Bekræft med Duo Security vha. Duo Mobile-appen, SMS, telefonopkald eller U2F-sikkerhedsnøgle.", + "duoDescV2": { + "message": "Angiv en kode genereret af Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Bekræftelseskoder vil blive e-mailet til dig." + "emailDescV2": { + "message": "Angiv en kode tilsendt pr. e-mail." }, "continue": { "message": "Fortsæt" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Angiv hovedadgangskoden for at ændre indstillinger for totrins-login." }, - "twoStepAuthenticatorDesc": { - "message": "Følg disse trin for at opsætte totrins-login vha. en godkendelses-app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download en godkendelses-app, såsom f.eks." }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download en totrins godkendelses-app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Behov for en totrins godkendelses-app? Download en af følgende" + "twoStepAuthenticatorInstructionInfix2": { + "message": "eller" }, - "iosDevices": { - "message": "iOS-enheder" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-enheder" + "continueToExternalUrlTitle": { + "message": "Fortsæt til $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-enheder" + "continueToExternalUrlDesc": { + "message": "Bitwarden forlades nu og et eksternt websted åbnes i et nyt vindue." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Disse apps anbefales, men andre godkendelses-apps vil også fungere." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Fortsæt til bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skan denne QR-kode med godkendelses-appen" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Bitwarden Authenticator muliggør at gemme godkendelsesnøgler og generere TOTP-koder til totrinsbekræftelsesstrømme. Læs mere på bitwarden.com-webstedet." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Skan QR-koden nedenfor med godkendelses-appen eller angiv nøglen." }, "key": { "message": "Nøgle" }, - "twoStepAuthenticatorEnterCode": { - "message": "Angiv den 6-cifrede bekræftelseskode fra appen" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Bekræftelseskode" }, "twoStepAuthenticatorReaddDesc": { "message": "Ønskes den føjet til en anden enhed, er nedenstående den QR-kode (eller nøgle), der kræves af godkendelses-appen." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Dette vindue lukkes automatisk om 5 sekunder" }, + "youMayCloseThisWindow": { + "message": "Dette vindue kan nu lukkes" + }, "includeAllTeamsFeatures": { "message": "Alle teamfunktioner, plus:" }, @@ -5618,7 +5630,7 @@ "message": "Rotering af faktureringssynk-tokenet vil ugyldiggøre det foregående token." }, "selfHostedServer": { - "message": "self-hosted" + "message": "selv-hostet" }, "customEnvironment": { "message": "Custom environment" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Eksportér klientrapport" }, - "invoiceNumberHeader": { - "message": "Fakturanummer", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Medlemsadgang" }, @@ -8431,21 +8439,55 @@ "message": " Kontakt kundesupport for at genoprette abonnementet." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Tildel grupper eller personer adgang til denne hemmelighed. Tilladelser sat for personer tilsidesætter tilladelser sat af grupper." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Tilføj personer eller grupper for at dele adgang til denne hemmelighed" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Tildel maskinkonti adgang til denne hemmelighed." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Tilføj maskinkontiadgang til denne hemmelighed" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Fjern adgang til denne hemmelighed" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Denne handling fjerner projektadgangen." + }, + "invoice": { + "message": "Faktura" + }, + "unassignedSeatsAvailable": { + "message": "Der er $SEATS$ utildelte pladser tilgængelige.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Kontakt udbyder-admin for tilkøb af yderligere pladser." + }, + "open": { + "message": "Åben", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uopkrævelig", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Kundeoplysninger" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "billingHistoryDescription": { + "message": "Download en CSV-fil for at få klientoplysninger for hver faktureringsdato. Forholdsmæssige gebyrer er ikke inkluderet i CSV og kan variere ift. den tilknyttede faktura. For de mest nøjagtige faktureringsoplysninger, se de månedlige fakturaer.", + "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." } } diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 98fef1f1bfd..bb7bb507407 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -714,7 +714,7 @@ "message": "Konto erstellen" }, "setAStrongPassword": { - "message": "Ein starkes Passwort festlegen" + "message": "Lege ein starkes Passwort fest" }, "finishCreatingYourAccountBySettingAPassword": { "message": "Schließe die Erstellung deines Kontos ab, indem du ein Passwort festlegst" @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "authenticatorAppDesc": { - "message": "Verwenden Sie eine Authentifizierungs-App (wie zum Beispiel Authy oder Google Authenticator), um zeitbasierte Verifizierungscodes zu generieren.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Sicherheitsschlüssel" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Verwende einen YubiKey, um auf dein Konto zuzugreifen. Funtioniert mit YubiKey 4 Serie, 5 Serie und NEO Geräten." + "message": "Verwenden Sie einen YubiKey um auf Ihr Konto zuzugreifen. Funtioniert mit YubiKey 4, Nano 4, 4C und NEO Geräten." }, - "duoDesc": { - "message": "Verifizieren Sie mit Duo Security, indem Sie die Duo Mobile App, SMS, Anrufe oder U2F Sicherheitsschlüssel benutzen.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,7 +984,7 @@ "message": "Benutze einen FIDO U2F-kompatiblen Sicherheitsschlüssel, um auf dein Konto zuzugreifen." }, "u2fTitle": { - "message": "FIDO U2F-Sicherheitsschlüssel" + "message": "FIDO U2F Sicherheitsschlüssel" }, "webAuthnTitle": { "message": "FIDO2 WebAuthn" @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-Mail" }, - "emailDesc": { - "message": "Bestätigungscodes werden Ihnen per E-Mail zugesandt." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Fortsetzen" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Geben Sie Ihr Master-Passwort ein, um die Zwei-Faktor-Anmeldeeinstellungen zu ändern." }, - "twoStepAuthenticatorDesc": { - "message": "Führen Sie diese Schritte aus, um eine Zwei-Faktor-Anmeldung mit einer Authentifizierungs-App einzurichten:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Laden Sie sich eine Zwei-Faktor-Authentifizierungs-App herunter" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Brauchen Sie eine Zwei-Faktor-Authentifizierungs-App? Laden Sie eine der folgenden Apps herunter" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS-Gerät" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-Gerät" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-Gerät" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Diese Apps sind Empfehlungen. Andere Authentifizierungs-Apps funktionieren allerdings auch." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scannen Sie diesen QR-Code mit Ihrer Authentifizierungs-App" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Schlüssel" }, - "twoStepAuthenticatorEnterCode": { - "message": "Geben Sie den 6-stelligen Bestätigungs-Code aus der App ein" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Falls Sie es zu einem anderen Gerät hinzufügen müssen, finden Sie unten den QR-Code (oder Schlüssel), der von Ihrer Authentifizierungs-App benötigt wird." @@ -3750,13 +3759,13 @@ "message": "Deabonnieren" }, "atAnyTime": { - "message": "at any time." + "message": "jederzeit." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Indem Sie fortfahren, stimmen Sie unseren" }, "and": { - "message": "and" + "message": "und" }, "acceptPolicies": { "message": "Durch Anwählen dieses Kästchens erklärst du dich mit Folgendem einverstanden:" @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Dieses Fenster wird sich in 5 Sekunden automatisch schließen." }, + "youMayCloseThisWindow": { + "message": "Du kannst dieses Fenster schließen" + }, "includeAllTeamsFeatures": { "message": "Alle Teams-Funktionen, plus:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Kundenbericht exportieren" }, - "invoiceNumberHeader": { - "message": "Rechnungsnummer", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Mitgliederzugriff" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "Diese Aktion wird deinen Zugriff auf dieses Geheimnis entziehen." + }, + "invoice": { + "message": "Rechnung" + }, + "unassignedSeatsAvailable": { + "message": "Du hast $SEATS$ nicht zugewiesene Benutzerplätze zur Verfügung.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Kontaktiere deinen Anbieter-Administrator, um zusätzliche Benutzerplätze zu kaufen." + }, + "open": { + "message": "Offen", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uneinbringlich", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index 5618c45d8ee..6dd5cf09bf8 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Εφαρμογή Επαλήθευσης" }, - "authenticatorAppDesc": { - "message": "Χρησιμοποιήστε μια εφαρμογή επαλήθευσης (όπως το Authy ή Google Authenticator) για να δημιουργήσει κωδικούς επαλήθευσης με χρόνικο περιορισμό.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Κλειδί Ασφαλείας YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Χρησιμοποιήστε ένα YubiKey για να αποκτήσετε πρόσβαση στο λογαριασμό σας. Λειτουργεί με συσκευές σειράς YubiKey 4, 5 και συσκευές NEO." }, - "duoDesc": { - "message": "Επαληθεύστε με το Duo Security χρησιμοποιώντας την εφαρμογή Duo Mobile, μηνύματα SMS, τηλεφωνική κλήση ή κλειδί ασφαλείας U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Οι κωδικοί επαλήθευσης θα σας αποσταλούν μέσω email." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Συνέχεια" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Εισάγετε τον κύριο κωδικό για να τροποποιήσετε τις ρυθμίσεις σύνδεσης δύο βημάτων." }, - "twoStepAuthenticatorDesc": { - "message": "Ακολουθήστε αυτά τα βήματα για να ρυθμίσετε τη σύνδεση δύο βημάτων με μια εφαρμογή επαλήθευσης:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Λήψη μιας εφαρμογής επαλήθευσης, δύο παραγόντων" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Χρειάζεστε μια εφαρμογή επαλήθευσης δύο παραγόντων; Κατεβάστε μία από τις παρακάτω" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Συσκευές iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Συσκευές Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Συσκευές Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Προτείνονται αυτές οι εφαρμογές, ωστόσο, άλλες εφαρμογές επαλήθευσης θα λειτουργήσουν επίσης." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Σαρώστε αυτόν τον κώδικα QR με την εφαρμογή επαλήθευσης" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Κλειδί" }, - "twoStepAuthenticatorEnterCode": { - "message": "Καταχωρίστε τον 6ψήφιο κωδικό επαλήθευσης που προκύπτει από την εφαρμογή" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Σε περίπτωση που χρειαστεί να την προσθέσετε σε άλλη συσκευή, παρακάτω είναι ο κωδικός QR (ή το κλειδί) που απαιτείται από την εφαρμογή επαλήθευσης." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Όλα τα χαρακτηριστικά του Teams, συν:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 85c53c623f8..ce8cbe9dbbb 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended. However, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index 1201cb1c22b..39e95e7d30c 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended. However, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 4358ab5c36c..3c0dc4cda88 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aŭtentiga Programo" }, - "authenticatorAppDesc": { - "message": "Uzu aŭtentikan programon (kiel Authy aŭ Google Authenticator) por generi tempokontrolajn kodojn.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Sekureca Ŝlosilo de YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Uzu YubiKey por aliri vian konton. Funkcias kun YubiKey 4-serio, 5-serio kaj NEO-aparatoj." }, - "duoDesc": { - "message": "Kontrolu per Duo-Sekureco per la Duo Mobile-programo, SMS, telefona alvoko aŭ U2F-sekureca ŝlosilo.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -990,7 +990,7 @@ "message": "WebAuthn FIDO2" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Retpoŝto" }, - "emailDesc": { - "message": "Kontrolaj kodoj estos retpoŝtigitaj al vi." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Daŭrigi" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enigu vian ĉefan pasvorton por modifi du-paŝajn ensalutajn agordojn." }, - "twoStepAuthenticatorDesc": { - "message": "Sekvu ĉi tiujn paŝojn por agordi du-paŝan ensaluton per aŭtentikiga programo:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Elŝuti du-paŝan aŭtentikigan programon" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Ĉu vi bezonas du-paŝan aŭtentikigan programon? Elŝutu unu el la jenaj" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS-aparatoj" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-aparatoj" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Vindozaj aparatoj" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Ĉi tiuj programoj estas rekomendindaj, tamen ankaŭ aliaj aŭtentikigaj programoj funkcios." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skani ĉi tiun QR-kodon per via aŭtentikiga programo" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Konigilo" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enigu la rezultan 6-ciferan konfirmkodon de la programo" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Se vi bezonas aldoni ĝin al alia aparato, sube estas la QR-kodo (aŭ ŝlosilo) postulita de via aŭtentikiga programo." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Ĉiuj funkcioj de teamoj, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 7c6aa93d1be..3f741069531 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplicación de autenticación" }, - "authenticatorAppDesc": { - "message": "Utiliza una aplicación de autenticación (como Authy o Google Authenticator) para generar código de verificación basados en tiempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Llave de seguridad YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Usa un Yubikey para acceder a tu cuenta. Funciona con YubiKey 4, 4 Nano, 4C y dispositivos NEO." }, - "duoDesc": { - "message": "Verificar con Duo Security usando la aplicación Duo Mobile, SMS, llamada telefónica o llave de seguridad U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Correo electrónico" }, - "emailDesc": { - "message": "Los códigos de verificación te serán enviados por correo electrónico." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continuar" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Introduce tu contraseña maestra para modificar las opciones de autenticación en dos pasos." }, - "twoStepAuthenticatorDesc": { - "message": "Sigue estos pasos para configurar la autenticación en dos pasos con una aplicación autenticadora:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Descarga una aplicación autenticadora en dos pasos" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "¿Necesitas una aplicación de autenticación en dos pasos? Descarga una de las siguientes" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Dispositivos iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Dispositivos Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Dispositivos Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Estas aplicaciones son recomendadas, sin embargo, otras aplicaciones autenticadoras también funcionarán." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Escanea este código QR con tu aplicación de autenticación" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Clave" }, - "twoStepAuthenticatorEnterCode": { - "message": "Introduzca el código de verificación de 6 dígitos generado en la aplicación de autentificación" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "En caso de que necesite agregarlo a otro dispositivo, a continuación se indica el código QR (o clave) requerido por su aplicación autenticadora." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Esta ventana se cerrará automáticamente en 5 segundos" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Todas las características de Equipos y además:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index e20f64414fa..72912ad0e64 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Autentimise rakendus" }, - "authenticatorAppDesc": { - "message": "Kasuta autentimise rakendust (näiteks Authy või Google Authenticator), et kasutada sisselogimiseks ajal baseeruvat kinnituskoodi.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP Turvaline võti" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Kasuta kontole ligipääsemiseks YubiKey-d. See töötab YubiKey 4, 5 ja NEO seadmetega." }, - "duoDesc": { - "message": "Kinnita Duo Security abil, kasutades selleks Duo Mobile rakendust, SMS-i, telefonikõnet või U2F turvavõtit.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Kinnituskoodid saadetakse e-postiga." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Jätka" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Kaheastmelise kinnitamise seadete muutmiseks pead sisestama ülemparooli." }, - "twoStepAuthenticatorDesc": { - "message": "Järgnevad juhised aitavad sul kaheastmelise kinnituse äpi ära seadistada:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Laadi kaheastmelise kinnitamise äpp alla" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Vajad kaheastmelise kinnitamise äppi? Proovi mõnda järgnevatest" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS seadmed" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android seadmed" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows seadmed" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Need äpid on soovituslikud. Saad ka teisi autentimise äppe kasutada." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skaneeri seda QR koodi oma autentimisrakendusega" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Võti" }, - "twoStepAuthenticatorEnterCode": { - "message": "Sisesta äpi kuvatav 6 kohaline kinnituskood" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Kui soovid lisada veel seadmeid, siis all on kuvatud QR kood (ehk võti), mida autentimisrakendusega kasutada saad." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Kõik Meeskonna funktsioonid, lisaks:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index f52c1cc6bdf..411e7bf4555 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Autentifikazio aplikazioa" }, - "authenticatorAppDesc": { - "message": "Erabili autentifikazio aplikazio bat (adibidez, Authy edo Google Authenticator) denboran oinarritutako egiaztatze-kodeak sortzeko.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP segurtasun-gakoa" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Erabili YubiKey zure kontuan sartzeko. YubiKey 4 series, 5 series eta NEO gailuekin dabil." }, - "duoDesc": { - "message": "Egiaztatu Duo Securityrekin Duo Mobile aplikazioa, SMS, telefono deia edo U2F segurtasun-gakoa erabiliz.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Emaila" }, - "emailDesc": { - "message": "Egiaztatze-kodeak email bidez bidaliko dira." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Jarraitu" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Sartu pasahitz nagusia bi urratseko saio hasierako ezarpenak aldatzeko." }, - "twoStepAuthenticatorDesc": { - "message": "Jarraitu, bi urratseko saio hasiera autentifikazio aplikazio batekin zehazteko:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Deskargatu bi urratseko autentifikazio aplikazio bat" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Bi urratseko autentifikazio aplikazio bat behar duzu? Deskargatu ondorengoetako bat" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS gailuak" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android gailuak" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows gailuak" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Aplikazio hauek dira gomendatuak, hala ere, beste aplikazio batzuk ere funtzionatuko dute." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Eskaneatu QR kode hau zure autentifikazio aplikazioarekin" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Gakoa" }, - "twoStepAuthenticatorEnterCode": { - "message": "Sartu aplikazioko 6 digituko egiaztatze-kodea" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Beste gailu bati gehitu behar badiozu, hona hemen autentifikazio-aplikazioak eskatzen duen QR kodea (edo gakoa)." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Taldeen ezaugarriak guztiak, gehi:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index da70f9ba308..39a44651628 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "برنامه احراز هویت" }, - "authenticatorAppDesc": { - "message": "از یک برنامه احراز هویت (مانند Authy یا Google Authenticator) استفاده کنید تا کدهای تأیید بر پایه زمان تولید کنید.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "کلید امنیتی YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "از یک YubiKey برای دسترسی به حسابتان استفاده کنید. با دستگاه های YubiKey سری 4، سری 5 و NEO کار می‌کند." }, - "duoDesc": { - "message": "با Duo Security با استفاده از برنامه تلفن همراه، پیامک، تماس تلفنی، یا کلید امنیتی U2F تأیید کنید.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "ایمیل" }, - "emailDesc": { - "message": "کد تأیید برایتان ارسال می‌شود." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "ادامه" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "کلمه عبور اصلی خود را برای تغییر تنظیمات ورود به سیستم دو مرحله ای وارد کنید." }, - "twoStepAuthenticatorDesc": { - "message": "برای راه‌اندازی ورود دو مرحله‌ای با یک برنامه احراز هویت، این مراحل را دنبال کنید:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "دانلود یک برنامه احراز هویت دو مرحله ای" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "به یک برنامه احراز هویت دو مرحله ای نیاز دارید؟ یکی از موارد زیر را دانلود کنید" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "دستگاه‌های iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "دستگاه Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "دستگاه Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "این برنامه‌ها توصیه می‌شوند، با این حال، سایر برنامه‌های احراز هویت نیز کار خواهند کرد." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "این کد QR را با برنامه احراز هویت خود اسکن کنید" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "کلید" }, - "twoStepAuthenticatorEnterCode": { - "message": "کد تأیید 6 رقمی حاصل را از برنامه وارد کنید" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "در صورت نیاز به افزودن آن به دستگاه دیگر، کد QR (یا کلید) مورد نیاز برنامه احراز هویت شما در زیر آمده است." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "همه ویژگی های تیم، به علاوه:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 97e32bc8255..3630a888f8e 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Todennussovellus" }, - "authenticatorAppDesc": { - "message": "Vahvista kirjautuminen todennussoveluksen (esim. Authy ja Google/Microsoft Authenticator) luomilla aikarajallisilla todennuskoodeilla.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Vahvista kirjatuminen YubiKey-todennuslaiteella. Toimii YubiKey 4 ja 5 -sarjojen sekä NEO -laitteiden kanssa." }, - "duoDesc": { - "message": "Vahvista kirjautuminen Duo Securityn avulla käyttäen Duo Mobile ‑sovellusta, tekstiviestiä, puhelua tai U2F-todennuslaitetta.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Sähköposti" }, - "emailDesc": { - "message": "Vahvista kirjautuminen sähköpostitse lähetettävällä todennuskoodilla." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Jatka" @@ -1285,7 +1285,7 @@ "message": "KDF-toistot" }, "kdfIterationsDesc": { - "message": "Korkeampi KDF-toistojen määrä suojaa sinua raakaa laskentatehoa hyväksikäyttäviltä murtoyrityksiltä. Suosittelemme arvoksi vähintään $VALUE$.", + "message": "Korkeampi KDF-toistojen määrä vahvistaa pääsalasanasi suojausta väsytyshyökkäyksien varalta. Suosittelemme arvoksi vähintään $VALUE$.", "placeholders": { "value": { "content": "$1", @@ -1313,7 +1313,7 @@ "message": "KDF-rinnakkaisuus" }, "argon2Desc": { - "message": "Korkeammat KDF-toistojen, -muistin ja -rinnakkaisuuksien määrät voivat suojata pääsalasanaasi murtautujien väsytyshyökkäyksiltä." + "message": "Korkeammat KDF-toistojen, -muistin ja -rinnakkaisuuksien määrät vahvistavat pääsalasanasi suojausta väsytyshyökkäyksien varalta." }, "changeKdf": { "message": "Vaihda KDF-asetuksia" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Syötä pääsalasanasi muokataksesi kaksivaiheisen kirjautumisen asetuksia." }, - "twoStepAuthenticatorDesc": { - "message": "Määritä kaksivaiheinen kirjautuminen todennussovelluksella seuraamalla näitä vaiheita:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Lataa kaksivaiheisen kirjautumisen todennussovellus" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Tarvitsetko todennussovelluksen kaksivaiheista kirjautumista varten? Lataa jokin seuraavista" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS-laitteet" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-laitteet" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-laitteet" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Suosittelemme näitä sovelluksia, mutta myös muut todennussovellukset toimivat." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skannaa tämä QR-koodi todennussovelluksellasi" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Avain" }, - "twoStepAuthenticatorEnterCode": { - "message": "Syötä 6-numeroinen todennuskoodi todennussovelluksestasi" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Jos sinun on lisättävä tai siirrettävä todennus toiseen laitteeseen, löydät alta todennussovelluksesi tarvitseman QR-koodin (tai avaimen)." @@ -3126,7 +3135,7 @@ } }, "removeUserIdAccess": { - "message": "Poista käyttäjän $ID$ käyttöoikeus", + "message": "Mitätöi käyttäjän $ID$ käyttöoikeus", "placeholders": { "id": { "content": "$1", @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Tämä ikkuna sulkeutuu automaattisesti 5 sekunnin kuluttua" }, + "youMayCloseThisWindow": { + "message": "Voit sulkea tämän ikkunan" + }, "includeAllTeamsFeatures": { "message": "Kaikki Teams-ominaisuudet, sekä:" }, @@ -7221,19 +7233,19 @@ "message": "Henkilöiden poistaminen palvelutililtä ei poista heidän luomiaan käyttötunnisteita. Parasta suojauskäytäntöä varten on suositeltavaa mitätöidä palvelutililtä poistettujen henkilöiden luomat tunnukset." }, "smAccessRemovalWarningProjectTitle": { - "message": "Poista projektin käyttöoikeus" + "message": "Mitätöi projektin käyttöoikeus" }, "smAccessRemovalWarningProjectMessage": { - "message": "Tämä poistaa käyttöoikeutesi projektiin." + "message": "Tämä mitätöi käyttöoikeutesi projektiin." }, "smAccessRemovalWarningSaTitle": { - "message": "Poista palvelutilin käyttöoikeus" + "message": "Mitätöi palvelutilin käyttöoikeus" }, "smAccessRemovalWarningSaMessage": { - "message": "Tämä poistaa käyttöoikeutesi palvelutiliin." + "message": "Tämä mitätöi käyttöoikeutesi palvelutiliin." }, "removeAccess": { - "message": "Poista käyttöoikeus" + "message": "Mitätöi käyttöoikeus" }, "checkForBreaches": { "message": "Tarkasta esiintyykö salasanaa tunnetuissa tietovuodoissa" @@ -7286,7 +7298,7 @@ "message": "Vaadi nykyisiä jäseniä vaihtamaan salasanansa" }, "smProjectDeleteAccessRestricted": { - "message": "Käyttöoikeutesi eivät salli tämän projektin poistamista", + "message": "Sinulla ei ole oikeutta poistaa tätä projektia", "description": "The individual description shown to the user when the user doesn't have access to delete a project." }, "smProjectsDeleteBulkConfirmation": { @@ -7669,7 +7681,7 @@ "message": "Onko sinulla jo tili?" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Näytä/piilota sivuvalikko" }, "skipToContent": { "message": "Siirry sisältöön" @@ -7727,10 +7739,10 @@ "message": "Oikeutesi eivät riitä kokoelman hallintaan." }, "grantAddAccessCollectionWarningTitle": { - "message": "Puuttuvat \"Voi hallita\" -käyttöoikeudet" + "message": "\"Voi hallita\" -käyttöoikeus puuttuu" }, "grantAddAccessCollectionWarning": { - "message": "Myönnä ”Voi hallita” -oikeudet, jotka mahdollistavat kokoelman täydellisen hallinnan, mukaanlukien sen poistamisen." + "message": "Myönnä ”Voi hallita” -oikeus, joka mahdollistaa kokoelman täydellisen hallinnan, mukaan lukien sen poistamisen." }, "grantCollectionAccess": { "message": "Myönnä ryhmille tai henkilöille kokoelman käyttöoikeus." @@ -8056,10 +8068,10 @@ "message": "Henkilöiden poistaminen konetililtä ei poista heidän luomiaan käyttötunnisteita. Parasta suojauskäytäntöä varten on suositeltavaa mitätöidä konetililtä poistettujen henkilöiden luomat tunnisteet." }, "smAccessRemovalWarningMaTitle": { - "message": "Poista konetilin käyttöoikeus" + "message": "Mitätöi konetilin käyttöoikeus" }, "smAccessRemovalWarningMaMessage": { - "message": "Tämä poistaa käyttöoikeutesi konetiliin." + "message": "Tämä mitätöi käyttöoikeutesi konetiliin." }, "machineAccountsIncluded": { "message": "Sisältää $COUNT$ konetiliä", @@ -8321,7 +8333,7 @@ "message": "Organisaation nimi vaihdettiin" }, "providerPlan": { - "message": "Hallittu palvelutoimittaja" + "message": "Hallintapalvelun toimittaja" }, "orgSeats": { "message": "Organisaation käyttäjäpaikat" @@ -8381,14 +8393,14 @@ "message": "Näytettäviä päätteitä ei ole" }, "providerBillingEmailHint": { - "message": "Tämä sähköpostiosoite vastaanottaa kaikki tähän palveluntarjoajaan liittyvät laskut", + "message": "Tämä sähköpostiosoite vastaanottaa kaikki tätä toimittajaa koskevat laskut", "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": "Tunnista tietoturvariskit tarkastelemalla jäsenten pääsytietoja" }, "onlyAvailableForEnterpriseOrganization": { - "message": "Quickly view member access across the organization by upgrading to an Enterprise plan." + "message": "Tarkastele jäsenten pääsyä organisaation tietoihin päivittämällä Enterprise-tilaukseen." }, "date": { "message": "Päiväys" @@ -8396,30 +8408,26 @@ "exportClientReport": { "message": "Vie pääteraportti" }, - "invoiceNumberHeader": { - "message": "Laskun numero", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { - "message": "Member access" + "message": "Jäsenten pääsytiedot" }, "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": "Varmista, että jäsenillä on oikeiden käyttäjätietojen käyttöoikeus ja että heidän tilinsä on suojattu. Tämän raportin avulla saat CSV-tiedoston käyttäjien oikeuksista ja tiliasetuksista." }, "higherKDFIterations": { - "message": "Higher KDF iterations can help protect your master password from being brute forced by an attacker." + "message": "Korkeampi KDF-toistojen määrä vahvistaa pääsalasanasi suojausta väsytyshyökkäyksien varalta." }, "incrementsOf100,000": { - "message": "increments of 100,000" + "message": "100 000 välein" }, "smallIncrements": { - "message": "small increments" + "message": "vähitellen" }, "kdfIterationRecommends": { - "message": "We recommend 600,000 or more" + "message": "Vähimmäissuositus on 600 000" }, "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": "Vanhemmilla laitteilla liian korkea KDF-arvo voi aiheuttaa suorituskykyongelmiin. Lisää arvoa $VALUE$ ja kokeile muutoksia laitteillasi.", "placeholders": { "value": { "content": "$1", @@ -8428,24 +8436,58 @@ } }, "providerReinstate": { - "message": " Contact Customer Support to reinstate your subscription." + "message": " Aktivoi tilauksesi uudelleen olemalla yhteydessä asiakaspalveluun." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Myönnä ryhmille tai henkilöille salaisuuden käyttöoikeus. Henkilökohtaiset käyttöoikeudet ohittavat ryhmien määrittämät oikeudet." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Myönnä salaisuuden käyttöoikeus lisäämällä henkilöitä tai ryhmiä" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Myönnä konetileille salaisuuden käyttöoikeus." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Myönnä salaisuuden käyttöoikeus lisäämällä konetilejä" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Mitätöi salaisuuden käyttöoikeus" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Tämä mitätöi käyttöoikeutesi salaisuuteen." + }, + "invoice": { + "message": "Lasku" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Avaa", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Keräämätön", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Lataa CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index defddd004e0..b32db0b0ed4 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Gumamit ng authenticator app (tulad ng Authy o Google Authenticator) para gumawa ng time-based na code pamberipika.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Gumamit ng YubiKey para ma-access ang account mo. Pwedeng gumamit ng YubiKey 4 series, 5 series, at NEO na mga device." }, - "duoDesc": { - "message": "Magberipika sa Duo Security gamit ang Duo Mobile app, SMS, tawag, o U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Ii-email ang mga code pamberipika sa'yo." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Magpatuloy" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Ipasok ang master password mo para baguhin ang mga setting ng dalawang-hakbang na pag-log in." }, - "twoStepAuthenticatorDesc": { - "message": "Gawin ito para mai-set up ang dalawang-hakbang na pag-log in gamit ang isang authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Mag-download ng isang two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Kailangan ng two-step authenticator app? I-download ang isa sa mga sumusunod" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Mga iOS device" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Mga Android device" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Mga Windows device" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Inirerekomenda ang mga app na ito, pero pwede rin ang iba pang mga app pang-authenticate." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "I-scan ang QR code na ito gamit ang authenticator app mo" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Ipasok ang 6 na numerong code pamberipika galing sa app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Kung kailangan mo itong idagdag sa iba pang device, nasa ibaba ang QR code (o key) na kailangan ng authenticator app mo." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Lahat ng mga Koponan tampok, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index c8257997a2c..7adab3f4cf5 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -216,7 +216,7 @@ "message": "Afficher/Masquer" }, "toggleCollapse": { - "message": "Déplier ou replier", + "message": "Déplier / replier", "description": "Toggling an expand/collapse state." }, "generatePassword": { @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Application d'authentification" }, - "authenticatorAppDesc": { - "message": "Utilisez une application d'authentification (comme Authy ou Google Authenticator) pour générer des codes de vérification basés sur le temps.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Entrez un code généré par une application d'authentification comme Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Clé de sécurité OTP YubiKey" + "yubiKeyTitleV2": { + "message": "Clé de sécurité OTP de Yubico" }, "yubiKeyDesc": { "message": "Utilisez une YubiKey pour accéder à votre compte. Fonctionne avec les YubiKey séries 4, séries 5 et NEO." }, - "duoDesc": { - "message": "Vérifiez avec Duo Security à l'aide de l'application Duo Mobile, d'un SMS, d'un appel téléphonique ou d'une clé de sécurité U2F.", + "duoDescV2": { + "message": "Entrez un code généré par Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Courriel" }, - "emailDesc": { - "message": "Les codes de vérification vous seront envoyés par courriel." + "emailDescV2": { + "message": "Entrez le code envoyé à votre adresse courriel." }, "continue": { "message": "Continuer" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Saisissez votre mot de passe principal pour modifier les paramètres d'authentification à deux facteurs." }, - "twoStepAuthenticatorDesc": { - "message": "Suivre ces étapes pour mettre en place l''authentification à deux facteurs avec une application d'authentification :" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Télécharger une application d'authentification telle que" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Télécharger une application d'authentification à deux facteurs" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Besoin d'une application d'authentification à deux facteurs ? Téléchargez en une parmi les suivantes" + "twoStepAuthenticatorInstructionInfix2": { + "message": "ou" }, - "iosDevices": { - "message": "Appareils iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Appareils Android" + "continueToExternalUrlTitle": { + "message": "Continuer vers $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Appareils Windows" + "continueToExternalUrlDesc": { + "message": "Vous quittez Bitwarden et lancez un site web externe dans une nouvelle fenêtre." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Ces applications sont recommandées, mais d'autres applications d'authentification fonctionneront également." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continuer vers bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scannez ce QR code avec votre application d'authentification" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Bitwarden Authenticator vous permet de stocker les clés d'authentification et de générer des codes TOTP pour les demande d'authentification en 2 étapes. Apprenez-en plus sur le site web bitwarden.com." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scannez le code QR ci-dessous avec votre application d'authentification ou saisissez la clé." }, "key": { "message": "Clé" }, - "twoStepAuthenticatorEnterCode": { - "message": "Entrez le code de vérification à 6 chiffres fourni par l’application" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Code de vérification" }, "twoStepAuthenticatorReaddDesc": { "message": "Dans le cas où vous devez l’ajouter à un autre appareil, voici le code QR (ou clé) requis par votre application d'authentification." @@ -2392,7 +2401,7 @@ "message": "Fichier de licence" }, "licenseFileDesc": { - "message": "Votre fichier de licence sera nommé comme quelque chose comme $FILE_NAME$", + "message": "Votre fichier de licence aura un nom similaire à $FILE_NAME$", "placeholders": { "file_name": { "content": "$1", @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Cette fenêtre se fermera automatiquement dans 5 secondes" }, + "youMayCloseThisWindow": { + "message": "Vous pouvez fermer cette fenêtre" + }, "includeAllTeamsFeatures": { "message": "Toutes les fonctionnalités pour les équipes, plus :" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Exporter le rapport client" }, - "invoiceNumberHeader": { - "message": "Numéro de facture", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Accès des membres" }, @@ -8431,21 +8439,55 @@ "message": " Contactez le Support Client pour rétablir votre abonnement." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Autoriser les groupes ou les personnes à accéder à ce secret. Les permissions définies pour les personnes remplaceront les permissions définies par les groupes." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Ajouter des personnes ou des groupes pour partager l'accès à ce secret" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Accorder l'accès aux comptes de machine à ce projet." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Ajouter des comptes de machine pour accorder l'accès à ce secret" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Retirer l'accès à ce secret" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Cette action retirera votre accès à ce secret." + }, + "invoice": { + "message": "Facture" + }, + "unassignedSeatsAvailable": { + "message": "Vous avez $SEATS$ licences non-assignées disponibles.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contactez l'administrateur de votre fournisseur pour acheter des licences supplémentaires." + }, + "open": { + "message": "Ouvrir", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Ne peut pas être collecté", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Détails Du Client" + }, + "downloadCSV": { + "message": "Télécharger le fichier CSV" + }, + "billingHistoryDescription": { + "message": "Téléchargez un fichier CSV pour obtenir les détails du client pour chaque date de facturation. Les frais au prorata ne sont pas inclus dans le fichier CSV et peuvent varier de la facture liée. Pour obtenir les détails de facturation les plus exacts, reportez-vous à vos factures mensuelles.", + "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." } } diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 91fadde228a..c45fa99b2c0 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index cbcf8a4167f..a57764339fd 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "אפליקציית אימות" }, - "authenticatorAppDesc": { - "message": "השתמש באפליקצית אימות (כמו לדוגמא Authy או Google Authenticator) לייצור סיסמאות אימות מבוססות זמן.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "מפתח אבטחה OTP של YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "השתמש בYubiKey עבור גישה לחשבון שלך. עובד עם YubiKey מסדרה 4, סדרה 5, ומכשירי NEO." }, - "duoDesc": { - "message": "בצע אימות מול Duo Security באמצעות אפליקצית Duo לפלאפון, SMS, שיחת טלפון, או מפתח אבטחה U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -987,10 +987,10 @@ "message": "מפתח אבטחה FIDO U2F" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "אימייל" }, - "emailDesc": { - "message": "קודים לאימות יישלחו אליך באימייל." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "המשך" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "הזן את הסיסמה הראשית שלך בכדי לשנות הגדרות הנוגעות לכניסה דו-שלבית." }, - "twoStepAuthenticatorDesc": { - "message": "עקוב אחר הצעדים הבאים להגדרת כניסה דו-שלבית עם אפליקציית אימות:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "הורד אפליקצית אימות דו שלבית" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "צריך אפליקצית אימות דו שלבית? הורד את אחד מהבאות" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "מכשירי אייפון" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "מכשירי אנדרואיד" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "מכשירי ווינדוס" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "האפליקציות הללו הם המומלצות, אך ניתן לעבוד גם עם אפליקציות אימות אחרות." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "סרוק את קוד הQR הזה בעזרת אפליקציית האימות שלך" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "מפתח" }, - "twoStepAuthenticatorEnterCode": { - "message": "הכנס את קוד האימות בן 6 הספרות מהאפליקציה" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "במקרה שאתה צריך את אפשרות הכניסה זמינה גם במכשיר אחר, כאן ניתן למצוא את קוד הQR (או המפתח) הנחוץ לאפליקציית האימות במכשיר הנוסף." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "כל התכונות הקיימות ב\"צוות\", ובנוסף:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 9dcf18cd77f..bfaee7bd97a 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index d5aed564957..6446ae48dd1 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Autentifikatorska aplikacija" }, - "authenticatorAppDesc": { - "message": "Koristi autentifikatorsku aplikaciju (npr. Authy ili Google Authentifikator) za generiranje kontrolnih kodova.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP sigurnosni ključ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Koristi YubiKey za pristup svojem računu. Radi s YubiKey 4, 4 Nano, 4C i NEO uređajima." }, - "duoDesc": { - "message": "Potvrdi s Duo Security pomoću aplikacije Duo Mobile, SMS-om, telefonskim pozivom ili U2F sigurnosnim ključem.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-pošta" }, - "emailDesc": { - "message": "Verifikacijski kodovi će biti poslani e-poštom." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Nastavi" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Unesi glavnu lozinku za promjenu postavki prijave u dva koraka." }, - "twoStepAuthenticatorDesc": { - "message": "Za aktivaciju prijave u dva koraka autentifikatorskom aplikacijom slijedi ove korake:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Preuzmi aplikaciju za dvostruku autentifikaciju" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Trebaš aplikaciju za dvostruku autentifikaciju? Preuzmi jednu od ovih" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS uređaji" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android uređaji" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows uređaji" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Ove su aplikacije preporučene, no također je moguće koristiti i druge autentifikatorske aplikacije." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skeniraj ovaj QR kôd svojom autentifikatorskom aplikacijom" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Ključ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Unesi 6-znamenkasti kontrolni kôd iz autentifikatorske aplikacije" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Ako trebaš dodati novi uređaj, dolje se nalazi QR kôd (ili ključ) kojeg zahtijeva tvoja autentifikatorska aplikacija." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Sve značajke Team, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 20356f76f3a..108001dd3f0 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Hitelesítő alkalmazás" }, - "authenticatorAppDesc": { - "message": "Hitelesítő alkalmazás használata (mint például az Authy vagy a Google Authenticator) idő alapú ellenőrzőkód generálásához.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Adjunk meg egy hitelesítő alkalmazás, például a Bitwarden Authenticator által generált kódot.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP egyszeri időalapú jelszó biztonsági kulcs" + "yubiKeyTitleV2": { + "message": "YubiKey OTP biztonsági kulcs" }, "yubiKeyDesc": { "message": "YubiKey használata a fiók eléréséhez. Működik a YubiKey 4, 4 Nano, 4C, és NEO eszközökkel." }, - "duoDesc": { - "message": "Ellenőrzés Duo Security-val, a Duo Mobile alkalmazás, SMS, telefonhívás vagy U2F biztonsági kulcs használatával.", + "duoDescV2": { + "message": "Adjuk meg a Duo Security által generált kódot.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email cím" }, - "emailDesc": { - "message": "Az ellenőrző kódok emailben kerülnek elküldésre." + "emailDescV2": { + "message": "Adjuk meg az email címre elküldött kódot." }, "continue": { "message": "Folytatás" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "A kétlépéses bejelentkezési beállítások módosításához meg kell adni a mesterjelszót." }, - "twoStepAuthenticatorDesc": { - "message": "Kövesük a következő lépéseket a kétlépéses bejelentkezés beállításához egy hitelesítő alkalmazással:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Töltsünk le egy hitelesítő alkalmazást, mint például" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Kétlépéses hitelesítő alkalmazás letöltése" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Szükség van egy kétlépéses hitelesítő alkalmazásra? Töltsük le a következők egyikét." + "twoStepAuthenticatorInstructionInfix2": { + "message": "vagy" }, - "iosDevices": { - "message": "iOS eszközök" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android eszközök" + "continueToExternalUrlTitle": { + "message": "Tovább: $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows eszközök" + "continueToExternalUrlDesc": { + "message": "Kilépümk a Bitwardenből és egy külső webhelyet indítunk el egy új ablakban." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Ezek az alkalmazások ajánlottak, de más hitelesítő alkalmazások is működnek." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Folytatás a bitwarden.com webhelyen?" }, - "twoStepAuthenticatorScanCode": { - "message": "Ezt a kódot kell beolvasni a hitelesítő alkalmazással." + "twoStepContinueToBitwardenUrlDesc": { + "message": "A Bitwarden Authenticator lehetővé teszi hitelesítő kulcsok tárolását és TOTP kódok generálását a kétlépcsős ellenőrzési folyamatokhoz. Tudjunk meg többet a bitwarden.com webhelyen." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Olvassuk be az alábbi QR kódot a hitelesítő alkalmazással,vagy írjuk be a kulcsot." }, "key": { "message": "Kulcs" }, - "twoStepAuthenticatorEnterCode": { - "message": "Adjuk meg az alkalmazásból kapott 6 számjegyű ellenőrző kódot." + "twoStepAuthenticatorEnterCodeV2": { + "message": "Ellenőrző kód" }, "twoStepAuthenticatorReaddDesc": { "message": "Ha ezt egy másik eszközhöz is hozzá kell adni, lentebb található a hitelesítő alkalmazás QR kódja (vagy kulcsa)." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Ez az ablak 5 másodpercen belül automatikusan bezárul." }, + "youMayCloseThisWindow": { + "message": "Most már bezárható ez az ablak." + }, "includeAllTeamsFeatures": { "message": "Összes Csapat funkció, továbbá:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Ügyfél jelentés exportálás" }, - "invoiceNumberHeader": { - "message": "Számlaszám", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Tagi hozzáférés" }, @@ -8431,21 +8439,55 @@ "message": " Lépjünk kapcsolatba az ügyfélszolgálattal az előfizetés visszaállításához." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Adjunk hozzáférést csoportoknak vagy személyeknek ehhez a titkos kódhoz. A személyek számára beállított engedélyek felülírják a csoportok által beállított engedélyeket." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Személyek vagy csoportok hozzáadása a hozzáférés megosztásához ennél a tiktos kódnál" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Gépi fiókok elérésének engedélyezése ehhez a titkos kódhoz." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Gépi fiókok hozzáadása a titkos kód hozzáféréséhez" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Hozzáférés eltávolítása ennél a titkos kódnál" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Ez a művelet eltávolítja a hozzáférést ennél a titkos kódnál." + }, + "invoice": { + "message": "Számla" + }, + "unassignedSeatsAvailable": { + "message": "$SEATS$ kiosztatlan hely van.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "További helyek vásárlásához forduljunk a szolgáltatóhoz." + }, + "open": { + "message": "Megnyitás", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Begyűjthetetlen", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Ügyfél részletek" + }, + "downloadCSV": { + "message": "CSV letöltése" + }, + "billingHistoryDescription": { + "message": "Töltsük le a CSV fájlt, hogy minden számlázási dátumhoz megkapjuk az ügyfél részleteket. Az arányos költségeket a CSV nem tartalmazza és eltérhetnek a hivatkozott számlától. A legpontosabb számlázási részletekért tekintsük meg havi számlákat.", + "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." } } diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 00d57a40d4e..3a305736ffe 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplikasi Autentikasi" }, - "authenticatorAppDesc": { - "message": "Gunakan aplikasi autentikasi (seperti Authy atau Google Authenticator) untuk menghasilkan kode verifikasi berbasis waktu.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Kunci Keamanan OTP YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Gunakan YubiKey untuk mengakses akun Anda. Bekerja dengan YubiKey 4, 4 Nano, 4C, dan peranti NEO." }, - "duoDesc": { - "message": "Verifikasi dengan Duo Security menggunakan aplikasi Duo Mobile, SMS, panggilan telepon, atau kunci keamanan U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Surel" }, - "emailDesc": { - "message": "Kode verifikasi akan dikirim via email kepada Anda." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Lanjutkan" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Masukkan kata sandi utama Anda untuk mengubah pengaturan login dua langkah." }, - "twoStepAuthenticatorDesc": { - "message": "Ikuti langkah-langkah berikut untuk menyiapkan login dua langkah dengan aplikasi pengautentikasi:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Unduh aplikasi autentikator dua langkah" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Butuh aplikasi pengautentikasi dua langkah? Unduh salah satu dari yang berikut ini" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Perangkat iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Perangkat Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Perangkat Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Aplikasi ini direkomendasikan, namun aplikasi pengautentikasi lain juga akan berfungsi." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Pindai kode QR ini dengan aplikasi pengautentikasi Anda" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Kunci" }, - "twoStepAuthenticatorEnterCode": { - "message": "Masukkan 6 digit kode verifikasi yang dihasilkan dari aplikasi" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Jika Anda perlu menambahkannya ke perangkat lain, di bawah ini adalah kode QR (atau kunci) yang diperlukan oleh aplikasi autentikator Anda." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Semua fitur Teams, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 6db7dfca77d..d3658ff23a0 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "App di autenticazione" }, - "authenticatorAppDesc": { - "message": "Usa un'app di autenticazione (come Authy o Google Authenticator) per generare codici di verifica a tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chiave di sicurezza YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utilizza una YubiKey per accedere al tuo account. Funziona con dispositivi YubiKey serie 4, serie 5 e NEO." }, - "duoDesc": { - "message": "Verifica con Duo Security usando l'app Duo Mobile, SMS, chiamata telefonica, o chiave di sicurezza U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "I codici di verifica ti saranno inviati per email." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continua" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Inserisci la tua password principale per modificare le impostazioni di verifica in due passaggi." }, - "twoStepAuthenticatorDesc": { - "message": "Segui questi passi per impostare la verifica in due passaggi con un'app di autenticazione:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Scarica un'app di autenticazione" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Hai bisogno di un'app di autenticazione? Scarica una di queste" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Dispositivi iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Dispositivi Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Dispositivi Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Queste app sono consigliate, ma anche altre app di autenticazione andranno bene." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scansione questo codice QR con la tua app di autenticazione" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Chiave" }, - "twoStepAuthenticatorEnterCode": { - "message": "Inserisci il codice di verifica a 6 cifre che vedi nell'app di autenticazione" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In caso debba aggiungerlo a un altro dispositivo, questo è il codice QR (o la chiave) richiesta dalla tua app di autenticazione." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Questa finestra si chiuderà automaticamente tra 5 secondi" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Tutte le funzionalità Teams e in più:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 4d80d599a76..6ac9a801d98 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -588,7 +588,7 @@ "message": "ログアウトしました" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "アカウントからログアウトしました。" }, "loginExpired": { "message": "ログインセッションの有効期限が切れています。" @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "認証アプリ" }, - "authenticatorAppDesc": { - "message": "Authy や Google 認証システムなどの認証アプリで時限式の認証コードを生成してください。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP セキュリティキー" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "YubiKey を使ってアカウントにアクセスできます。 YubiKey 4、4 Nano、4C、NEOに対応しています。" }, - "duoDesc": { - "message": "Duo Mobile アプリや SMS、電話や U2F セキュリティキーを使って Duo Security で認証します。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "メールアドレス" }, - "emailDesc": { - "message": "確認コードをメールにお送りします。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "続ける" @@ -1076,10 +1076,10 @@ "message": "UUID をコピー" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "アクセストークンの更新エラー" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "リフレッシュトークンや API キーが見つかりませんでした。ログアウトして再度ログインしてください。" }, "warning": { "message": "注意" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "二段階認証の設定を変更するためにマスターパスワードを入力して下さい。" }, - "twoStepAuthenticatorDesc": { - "message": "認証アプリによる二段階認証を設定するために必要な手順:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "二段階認証アプリをダウンロード" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "二段階認証アプリが必要ですか?以下からダウンロードして下さい。" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS デバイス" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android デバイス" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows デバイス" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "これらのアプリがお勧めですが、他の認証アプリでも動作します。" + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "認証アプリでQRコードをスキャンして下さい。" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "キー" }, - "twoStepAuthenticatorEnterCode": { - "message": "認証アプリに表示された6桁の確認コードを入力して下さい。" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "別のデバイスの認証アプリを利用する場合、以下のQRコード(またはキー)が必要となります。" @@ -1748,10 +1757,10 @@ "message": "Bitwardenアプリの情報をDuoの管理パネルから入力して下さい。" }, "twoFactorDuoClientId": { - "message": "Client Id" + "message": "クライアント ID" }, "twoFactorDuoClientSecret": { - "message": "Client Secret" + "message": "クライアントシークレット" }, "twoFactorDuoApiHostname": { "message": "API のホスト名" @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "このウィンドウは5秒後に自動的に閉じます" }, + "youMayCloseThisWindow": { + "message": "ウィンドウを閉じて大丈夫です" + }, "includeAllTeamsFeatures": { "message": "すべてのチームの機能に加えて:" }, @@ -5618,37 +5630,37 @@ "message": "請求同期トークンを更新すると、前のトークンは無効になります。" }, "selfHostedServer": { - "message": "self-hosted" + "message": "自己ホスト型" }, "customEnvironment": { - "message": "Custom environment" + "message": "カスタム環境" }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "オンプレミスホストした Bitwarden のベース URL を指定してください。例: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "高度な設定では、各サービスのベース URL を個別に指定できます。" }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "ベース サーバー URL または少なくとも 1 つのカスタム環境を追加する必要があります。" }, "apiUrl": { - "message": "API server URL" + "message": "API サーバー URL" }, "webVaultUrl": { - "message": "Web vault server URL" + "message": "ウェブ保管庫サーバー URL" }, "identityUrl": { - "message": "Identity server URL" + "message": "ID サーバー URL" }, "notificationsUrl": { - "message": "Notifications server URL" + "message": "通知サーバー URL" }, "iconsUrl": { - "message": "Icons server URL" + "message": "アイコンサーバー URL" }, "environmentSaved": { - "message": "Environment URLs saved" + "message": "環境 URL が保存されました" }, "selfHostingTitle": { "message": "セルフホスティング" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "クライアントレポートをエクスポート" }, - "invoiceNumberHeader": { - "message": "請求書番号", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "メンバーアクセス" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "このシークレットへのアクセスを削除します。" + }, + "invoice": { + "message": "請求書" + }, + "unassignedSeatsAvailable": { + "message": "未割り当てのライセンスが $SEATS$ 個あります。", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "追加のライセンスを購入するには、プロバイダの管理者に連絡してください。" + }, + "open": { + "message": "未払い", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "回収不能", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "クライアントの詳細" + }, + "downloadCSV": { + "message": "CSV をダウンロード" + }, + "billingHistoryDescription": { + "message": "請求日ごとにクライアントの詳細を取得するには、CSV をダウンロードしてください。 分割料金は CSV に含まれておらず、リンクされた請求書によって異なる場合があります。 最も正確な請求の詳細については、毎月の請求書を参照してください。", + "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." } } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index f61832a9b00..32f1d03a927 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "ავთენტიკატორი აპი" }, - "authenticatorAppDesc": { - "message": "გამოიყენეთ ავთენტიკატორი აპი (როგორიცაა Authy ან Google Authenticator-ი) რომ წამმოქმნათ დროზე დაფუძნებული ერთჯერადი კოდები.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "გამოიყენეთ YubiKey ანგარიშში შესასვლელად. მუშაობს YubiKey 4 სერია, 5 სერია, და NEO მოწყობილობებთან." }, - "duoDesc": { - "message": "დაადასტურეთ Duo Security-ი Duo მობილური აპლიკაციის, სმს-ის, სატელეფონო ზარის, ან U2F უსაფრთხოების გასაღებით.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "ელ-ფოსტა" }, - "emailDesc": { - "message": "ერთჯერადი კოდი ელ-ფოსტაზე გამოგეგზავნებათ." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "გაგრძელება" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "მიყევით ამ ნაბიჯებს რომ გამართოთ ორსაფეხურიანი ავტორიზაცია ავთენტიკატორი აპით:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "ჩამოტვირთეთ ორსაფეხურიანი ავთენტიკატორი აპი" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "გჭირდებატ ორსაფეხურიანი ავთენტიკატორი აპი? ჩამოტვირთეთ ერთერთი რომელიმე შემდეგიდან" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "ეს აპლიკაციები არის რეკომენდირებული, თუმცა, სხვა ავთენტიკატორი აპპლიკაციებიც იმუშავებს." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "დაასკანირეთ ეს QR-კოდი თქვენი ავთენტიკატორი აპით" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "შეიყვანეთ გამოსახული 6 ნიშნა ერთჯერადი კოდი აპლიკაციიდან" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "იმ შემთხვევაში თუ გჭირდებათ სხვა მოწყობილობის დამატება, ქვემოთ არის QR-კოდი (ან გასაღები) მოთხოვნილი თქვენი ავთენტიკატორი აპისგან." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index 91fadde228a..c45fa99b2c0 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index a28d195b484..df0d63f1c52 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್" }, - "authenticatorAppDesc": { - "message": "ಸಮಯ ಆಧಾರಿತ ಪರಿಶೀಲನಾ ಕೋಡ್‌ಗಳನ್ನು ರಚಿಸಲು ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸಿ (ಆಥಿ ಅಥವಾ ಗೂಗಲ್ ಅಥೆಂಟಿಕೇಟರ್).", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "ಯುಬಿಕೆ ಒಟಿಪಿ ಭದ್ರತಾ ಕೀ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "ನಿಮ್ಮ ಖಾತೆಯನ್ನು ಪ್ರವೇಶಿಸಲು ಯುಬಿಕೆ ಬಳಸಿ. ಯುಬಿಕೆ 4 ಸರಣಿ, 5 ಸರಣಿಗಳು ಮತ್ತು ಎನ್ಇಒ ಸಾಧನಗಳೊಂದಿಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ." }, - "duoDesc": { - "message": "ಡ್ಯುಯೊ ಮೊಬೈಲ್ ಅಪ್ಲಿಕೇಶನ್, ಎಸ್‌ಎಂಎಸ್, ಫೋನ್ ಕರೆ ಅಥವಾ ಯು 2 ಎಫ್ ಭದ್ರತಾ ಕೀಲಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಡ್ಯುಯೊ ಸೆಕ್ಯುರಿಟಿಯೊಂದಿಗೆ ಪರಿಶೀಲಿಸಿ.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "ಇಮೇಲ್" }, - "emailDesc": { - "message": "ಪರಿಶೀಲನೆ ಕೋಡ್‌ಗಳನ್ನು ನಿಮಗೆ ಇಮೇಲ್ ಮಾಡಲಾಗುತ್ತದೆ." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "ಮುಂದುವರಿಸಿ" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "ಎರಡು ಹಂತದ ಲಾಗಿನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ನಿಮ್ಮ ಮಾಸ್ಟರ್ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸಿ." }, - "twoStepAuthenticatorDesc": { - "message": "ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್‌ನೊಂದಿಗೆ ಎರಡು-ಹಂತದ ಲಾಗಿನ್ ಅನ್ನು ಹೊಂದಿಸಲು ಈ ಹಂತಗಳನ್ನು ಅನುಸರಿಸಿ:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "ಎರಡು ಹಂತದ ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "ಎರಡು-ಹಂತದ ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್ ಅಗತ್ಯವಿದೆಯೇ? ಕೆಳಗಿನವುಗಳಲ್ಲಿ ಒಂದನ್ನು ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "ಐಒಎಸ್ ಸಾಧನಗಳು" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "ಆಂಡ್ರಾಯ್ಡ್ ಸಾಧನಗಳು" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "ವಿಂಡೋಸ್ ಸಾಧನಗಳು" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "ಈ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ, ಆದಾಗ್ಯೂ, ಇತರ ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಸಹ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "ನಿಮ್ಮ ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್‌ನೊಂದಿಗೆ ಈ ಕ್ಯೂಆರ್ ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "ಕೀ" }, - "twoStepAuthenticatorEnterCode": { - "message": "ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಫಲಿತಾಂಶದ 6 ಅಂಕಿಯ ಪರಿಶೀಲನೆ ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "ಒಂದು ವೇಳೆ ನೀವು ಅದನ್ನು ಮತ್ತೊಂದು ಸಾಧನಕ್ಕೆ ಸೇರಿಸಬೇಕಾದರೆ, ನಿಮ್ಮದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅಗತ್ಯವಿರುವ ಕ್ಯೂಆರ್ ಕೋಡ್ (ಅಥವಾ ಕೀ) ಕೆಳಗೆ ಇದೆ." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "ಎಲ್ಲಾ ತಂಡಗಳ ವೈಶಿಷ್ಟ್ಯಗಳು, ಜೊತೆಗೆ:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 71e571bebe8..e954dd2eeca 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "인증 앱" }, - "authenticatorAppDesc": { - "message": "인증 앱(Authy, Google OTP 등)을 통하여 일회용 인증 코드를 생성합니다.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 보안 키" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "YubiKey를 사용하여 사용자의 계정에 접근합니다. YubiKey 4, 4 Nano, 4C 및 NEO 기기를 사용할 수 있습니다." }, - "duoDesc": { - "message": "Duo Mobile 앱, SMS, 전화 통화를 사용한 Duo Security 또는 U2F 보안 키를 사용하여 인증하세요.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "이메일" }, - "emailDesc": { - "message": "인증 코드가 담긴 이메일을 다시 보냅니다." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "계속" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "2단계 로그인 설정을 수정하려면 마스터 암호를 입력하십시오." }, - "twoStepAuthenticatorDesc": { - "message": "다음 단계에 따라 인증자 앱으로 2단계 로그인 설정:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "2단계 인증자 앱 다운로드" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "2단계 인증자 앱이 필요하십니까? 다음 중 하나를 다운로드하세요" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS 기기" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android 기기" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows 기기" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "이 QR 코드를 인증 앱으로 스캔" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "키" }, - "twoStepAuthenticatorEnterCode": { - "message": "앱에서 결과로 나온 6자리 인증코드를 입력하십시오" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "다른 장치에 추가해야 하는 경우, 아래의 QR코드(혹은 키) 가 인증자 앱에 필요합니다." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "모든 팀 기능, 추가로:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 46840a497be..e968f6fcfe8 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -639,7 +639,7 @@ "message": "Divpakāpju pieteikšanās netiek atbalstīta piekļuves atslēgām. Jāatjaunina lietotne, lai pieteiktos." }, "loginWithPasskeyInfo": { - "message": "Piekļuves atslēga ir izmantojama, lai automātiski pieteiktos bez paroles. Biometrija, piemēram, sejas atpazīšana vai pirkstu nospiedums, vai cits FIDO2 drošības veids apstiprinās identitāti." + "message": "Piekļuves atslēga ir izmantojama, lai automātiski pieteiktos bez paroles. Biometrija, piemēram, sejas atpazīšana vai pirkstu nospiedums, vai cits FIDO2 drošības veids apliecinās identitāti." }, "newPasskey": { "message": "Jauna piekļuves atslēga" @@ -729,7 +729,7 @@ "message": "Pieteikties" }, "verifyIdentity": { - "message": "Apliecināt savu identitāti" + "message": "Jāapliecina sava identitāte" }, "logInInitiated": { "message": "Uzsākta pieteikšanās" @@ -768,7 +768,7 @@ "message": "Galvenās paroles norāde" }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Ja tiks aizmirsta parole, tās norādi var nosūtīt uz e-pasta adresi. $CURRENT$/$MAXIMUM$ lielākais pieļaujamais rakstzīmju skaits.", "placeholders": { "current": { "content": "$1", @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Autentificētāja lietotne" }, - "authenticatorAppDesc": { - "message": "Izmanto autentificētāja lietotni (piemēram, Authy vai Google autentifikators), lai izveidotu laikā balstītus apstiprinājuma kodus!", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP drošības atslēga" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "YubiKey ir izmantojams, lai piekļūtu savam kontam. Darbojas ar YubiKey 4. un 5. sēriju un NEO ierīcēm." }, - "duoDesc": { - "message": "Ar Duo Security apliecināšanu var veikt ar Duo Mobile lietotni, īsziņu, tālruņa zvanu vai U2F drošības atslēgu.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-pasts" }, - "emailDesc": { - "message": "Apstiprinājuma kodi tiks nosūtīti e-pastā." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Turpināt" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Jāievada galvenā parole, lai mainītu divpakāpju pieteikšanās iestatījumus." }, - "twoStepAuthenticatorDesc": { - "message": "Jāizpilda šie soļi, lai uzstādītu divpakāpju pieteikšanos ar autentificētāja lietotni:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Jālejupielādē divpakāpju autentificētāja lietotne" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Ir nepieciešama divpakāpju autentificētāja lietotne? Lejupielādē vienu no sekojošām" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS ierīces" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android ierīces" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows ierīces" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Šīs ir ieteicamās lietotnes, bet darbosies arī citas autentificētāja lietotnes." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Šis kvadrātkods ir jānolasa ar autentificētāja lietotni" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Atslēga" }, - "twoStepAuthenticatorEnterCode": { - "message": "Jāievada lietotnes izveidotais 6 ciparu apstiprināšanas kods" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Ja ir vajadzība pievienot citās ierīcēs, zemāk ir kvadrātkods (vai atslēga), kas ir izmantojams autentificētāja lietotnē." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Šis logs tiks automātiski aizvērts 5 sekunžu laikā" }, + "youMayCloseThisWindow": { + "message": "Šo logu var aizvērt" + }, "includeAllTeamsFeatures": { "message": "Visas vienību iespējas, kā arī:" }, @@ -4905,7 +4917,7 @@ "message": "Galvenās paroles apstiprināšana" }, "passwordConfirmationDesc": { - "message": "Šī darbība ir aizsargāta. Lai turpinātu, ir jāievada galvenā parole, lai apstiprinātu identitāti." + "message": "Šī darbība ir aizsargāta. Lai turpinātu, ir jāievada galvenā parole, lai apliecinātu savu identitāti." }, "reinviteSelected": { "message": "Atkārtoti nosūtīt uzaicinājumus" @@ -7669,7 +7681,7 @@ "message": "Jau ir konts?" }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Pārslēgt sānu pārvietošanās joslu" }, "skipToContent": { "message": "Pāriet uz saturu" @@ -8385,10 +8397,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": "Nosaki iespējamus drošības trūkumus ar dalībnieku piekļuves pārbaudīšanu" }, "onlyAvailableForEnterpriseOrganization": { - "message": "Quickly view member access across the organization by upgrading to an Enterprise plan." + "message": "Ātra dalībnieku piekļuves pārskatīšana apvienībā ar uzlabošanu uz plānu \"Uzņēmējdarbība\"." }, "date": { "message": "Datums" @@ -8396,15 +8408,11 @@ "exportClientReport": { "message": "Izgūt klienta atskaiti" }, - "invoiceNumberHeader": { - "message": "Rēķina numurs", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { - "message": "Member access" + "message": "Dalībnieku piekļuve" }, "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": "Nodrošini, ka dalībniekiem ir piekļuve pareizajiem piekļuves datiem un viņu konti ir droši. Šī atskaite ir izmantojama, lai iegūtu CSV ar dalībnieku piekļuvi un kontu konfigurāciju." }, "higherKDFIterations": { "message": "Lielāks KDF atkārtojumu skaits var palīdzēt aizsargāt galveno paroli pārlases uzbrukuma gadījumā." @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "Šī darbība noņems Tavu piekļuvi šim noslēpumam." + }, + "invoice": { + "message": "Rēķins" + }, + "unassignedSeatsAvailable": { + "message": "Ir pieejamas $SEATS$ nepiešķirtas vietas.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Jāsazinās ar nodrošinātāja pārvaldītāju, lai iegādātos papildu vietas." + }, + "open": { + "message": "Atvērts", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Nepiedzenams", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Informācija par klientiem" + }, + "downloadCSV": { + "message": "Lejupielādēt CSV" + }, + "billingHistoryDescription": { + "message": "Lejupielādēt CSV, lai iegūtu informāciju par klientiem katrā norēķinu datumā. Samērīgā sadalījuma maksas netiek iekļautas CSV un var atšķirties no saistītā rēķina. Visatbilstošāko norēķinu informāciju var iegūt ikmēneša rēķinos.", + "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." } } diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index f9d97996b08..78c4d96a2d5 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "ഓതന്റിക്കേറ്റർ ആപ്പ്" }, - "authenticatorAppDesc": { - "message": "സമയ-അടിസ്ഥാന പരിശോധന കോഡുകൾ സൃഷ്ടിക്കുന്നതിന് ഒരു ഓതന്റിക്കേറ്റർ അപ്ലിക്കേഷൻ (ഓത്തി അല്ലെങ്കിൽ Google ഓതന്റിക്കേറ്റർ പോലുള്ളവ) ഉപയോഗിക്കുക.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP സുരക്ഷാ കീ" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "നിങ്ങളുടെ അക്കൗണ്ട് ആക്സസ് ചെയ്യുന്നതിന് ഒരു യൂബിക്കി ഉപയോഗിക്കുക. YubiKey 4, 4 Nano, 4C, NEO ഉപകരണങ്ങളിൽ പ്രവർത്തിക്കുന്നു." }, - "duoDesc": { - "message": "Duo Mobile അപ്ലിക്കേഷൻ, എസ്എംഎസ്, ഫോൺ കോൾ അല്ലെങ്കിൽ യു 2 എഫ് സുരക്ഷാ കീ ഉപയോഗിച്ച് Duoസെക്യൂരിറ്റി ഉപയോഗിച്ച് പരിശോധിക്കുക.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -987,10 +987,10 @@ "message": "FIDO U2F സുരക്ഷാ കീ" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "ഇമെയിൽ" }, - "emailDesc": { - "message": "സ്ഥിരീകരണ കോഡുകൾ നിങ്ങൾക്ക് ഇമെയിൽ ചെയ്യും." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "തുടരുക" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "രണ്ട്-ഘട്ട ഓതന്റിക്കേറ്റർ അപ്ലിക്കേഷൻ ഡൗൺലോഡുചെയ്യുക" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS ഉപകരണങ്ങൾ" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android ഉപകരണങ്ങൾ" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows ഉപകരണങ്ങൾ" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "എല്ലാ ടീമുകളുടെ സവിശേഷതകളും, കൂടാതെ:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index 91fadde228a..c45fa99b2c0 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index 91fadde228a..c45fa99b2c0 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index e4a09d17ce6..b1ae23ff9cb 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Autentiseringsapp" }, - "authenticatorAppDesc": { - "message": "Bruk en autentiseringsapp (f․eks․ Authy eller Google Authenticator) for å generere tidsbegrensede verifiseringskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP-sikkerhetsnøkkel" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Bruk en YubiKey for å få tilgang til kontoen din. Virker med enheter av typene YubiKey 4, 4 Nano, 4C, og NEO." }, - "duoDesc": { - "message": "Verifiser med Duo Security gjennom Duo Mobile-appen, SMS, telefonsamtale, eller en U2F-sikkerhetsnøkkel.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Verifiseringskoder vil bli sendt til deg med E-post." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Fortsett" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Skriv inn ditt hovedpassord for å endre på 2-trinnsinnloggingsinnstillingene." }, - "twoStepAuthenticatorDesc": { - "message": "Følg disse trinnene for å sette opp 2-trinnsinnlogging med en autentiseringsapp:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Last ned en 2-trinnsinnloggingsapp" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Trenger du en 2-trinnsinnloggingsapp? Last ned en av de følgende" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS-enheter" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-enheter" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-enheter" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Disse appene er anbefalt, men andre autentiseringsapper vil også fungere." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skann denne QR-koden med din autentiseringsapp" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Nøkkel" }, - "twoStepAuthenticatorEnterCode": { - "message": "Skriv inn den påfølgende 6-sifrede verifiseringskoden fra appen" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Dersom du trenger å legge den til til en annen enhet, er QR-koden (eller -nøkkelen) som kreves av din autentiseringsapp nedenfor." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Alle Lag funksjoner, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index f53c0bb2418..181697d9546 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 7d44e48e485..d19b4e04d52 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticatie-app" }, - "authenticatorAppDesc": { - "message": "Gebruik een authenticatie-app (zoals Authy of Google Authenticator) om tijdgebaseerde authenticatiecodes te genereren.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Door een authenticatie-app zoals Bitwarden Authenticator gegenereerde code invoeren.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { + "yubiKeyTitleV2": { "message": "YubiKey OTP-beveiligingssleutel" }, "yubiKeyDesc": { "message": "Gebruik een YubiKey om toegang te krijgen tot je account. Werkt met YubiKey 4, 4 Nano, 4C en Neo-apparaten." }, - "duoDesc": { - "message": "Verifieer met Duo Security middels de Duo Mobile-app, sms, spraakoproep of een U2F-beveiligingssleutel.", + "duoDescV2": { + "message": "Door Duo Security gegenereerde code invoeren.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-mailadres" }, - "emailDesc": { - "message": "Je ontvangt verificatiecodes via e-mail." + "emailDescV2": { + "message": "Via e-mail verstuurde code invoeren." }, "continue": { "message": "Doorgaan" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Vul je hoofdwachtwoord in om je tweestapsaanmeldingsinstellingen te wijzigen." }, - "twoStepAuthenticatorDesc": { - "message": "Volg deze stappen om tweestapsaanmelding in te stellen met een authenticatie-app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download een authenticatie-app zoals" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download een tweestapsauthenticatie-app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Een tweestapsauthenticatie app nodig? Download een van de volgende" + "twoStepAuthenticatorInstructionInfix2": { + "message": "of" }, - "iosDevices": { - "message": "iOS-apparaten" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-apparaten" + "continueToExternalUrlTitle": { + "message": "Doorgaan naar $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-apparaten" + "continueToExternalUrlDesc": { + "message": "Je verlaat Bitwarden en start een externe website in een nieuw venster." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Deze apps zijn aanbevolen, maar andere authenticatie-apps werken ook." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Doorgaan naar bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan deze QR-code met je authenticatie-app" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Met Bitwarden Authenticator kunt je authenticatiesleutels opslaan en TOTP-codes voor tweestapsaanmelding genereren. Lees meer op de website bitwarden.com." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan de onderstaande QR-code met je authenticator-app of voer de sleutel in." }, "key": { "message": "Sleutel" }, - "twoStepAuthenticatorEnterCode": { - "message": "Voer de 6-cijferige verificatiecode uit je authenticatie-app in" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verificatiecode" }, "twoStepAuthenticatorReaddDesc": { "message": "In het geval dat je het aan een ander apparaat moet toevoegen, is hieronder de QR-code (of sleutel) die je authenticatie-app nodig heeft." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Dit scherm sluit automatisch over 5 seconden" }, + "youMayCloseThisWindow": { + "message": "Je kunt dit venster sluiten" + }, "includeAllTeamsFeatures": { "message": "Alle functionaliteit van Teams plus:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Klantenrapport exporteren" }, - "invoiceNumberHeader": { - "message": "Factuurnummer", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Ledentoegang" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "Hiermee trek je je toegang tot het project in." + }, + "invoice": { + "message": "Factuur" + }, + "unassignedSeatsAvailable": { + "message": "Je hebt $SEATS$ niet-toegewezen plaatsen beschikbaar.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Neem contact op met je beheerder om extra plaatsen te kopen." + }, + "open": { + "message": "Openen", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Oninbaar", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Klantgegevens" + }, + "downloadCSV": { + "message": "CSV downloaden" + }, + "billingHistoryDescription": { + "message": "Download een CSV om klantgegevens voor elke factuurdatum te krijgen. De CSV bevat geen pro rata kosten en kan afwijken van de gekoppelde factuur. Voor de meest nauwkeurige factureringsgegevens kun je je maandelijkse facturen raadplegen.", + "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." } } diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index 64739273666..b9029fedb58 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Autentiseringsapp" }, - "authenticatorAppDesc": { - "message": "Bruk ein app for autentisering (til dømes Authy eller Google Authenticator) for å generera tidsavgrensa verifiseringskodar.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS-einingar" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-einingar" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-einingar" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Nykel" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index 91fadde228a..c45fa99b2c0 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 1bf2135b7c0..07c01cd85ed 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplikacja uwierzytelniająca" }, - "authenticatorAppDesc": { - "message": "Użyj aplikacji mobilnej (np. Authy lub Google Authenticator) do generowania czasowych kodów weryfikacyjnych.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Wprowadź kod wygenerowany przez aplikację uwierzytelniającą, jak Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Klucz bezpieczeństwa YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Klucz bezpieczeństwa Yubico OTP" }, "yubiKeyDesc": { "message": "Użyj YubiKey jako metody dostępu do konta. Działa z YubiKey serii 4, serii 5 i urządzeniami NEO." }, - "duoDesc": { - "message": "Weryfikacja z użyciem Duo Security poprzez aplikację Duo Mobile, SMS, połączenie telefoniczne lub klucz bezpieczeństwa U2F.", + "duoDescV2": { + "message": "Wprowadź kod wygenerowany przez Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Adres e-mail" }, - "emailDesc": { - "message": "Kody weryfikacyjne zostaną wysłane do Ciebie wiadomością e-mail." + "emailDescV2": { + "message": "Wpisz kod wysłany na Twój adres e-mail." }, "continue": { "message": "Kontynuuj" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Wpisz hasło główne, aby zmienić ustawienia logowania dwustopniowego." }, - "twoStepAuthenticatorDesc": { - "message": "Wykonaj poniższe kroki, aby aktywować logowanie dwustopniowe przez aplikację uwierzytelniającą:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Pobierz aplikację uwierzytelniającą, taką jak" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Pobierz aplikację uwierzytelniającą" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Potrzebujesz aplikacji uwierzytelniającej? Pobierz jedną z nich" + "twoStepAuthenticatorInstructionInfix2": { + "message": "lub" }, - "iosDevices": { - "message": "Urządzenia z systemem iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Urządzenia z systemem Android" + "continueToExternalUrlTitle": { + "message": "Kontynuować do $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Urządzenia z systemem Windows" + "continueToExternalUrlDesc": { + "message": "Opuszczasz Bitwarden i uruchamiasz zewnętrzną stronę internetową w nowym oknie." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Te aplikacje uwierzytelniające są zalecane, jednak inne również będą działać." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Kontynuować do bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Zeskanuj kod QR w aplikacji uwierzytelniającej" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Bitwarden Authenticator pozwala na przechowywanie kluczy uwierzytelniających i generowanie kodów TOTP do dwuetapowego procesu weryfikacji. Dowiedz się więcej na stronie bitwarden.com." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Zeskanuj poniższy kod QR za pomocą aplikacji uwierzytelniającej lub wprowadź klucz." }, "key": { "message": "Klucz" }, - "twoStepAuthenticatorEnterCode": { - "message": "Wpisz 6-cyfrowy kod weryfikacyjny z aplikacji uwierzytelniającej" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Kod weryfikacyjny" }, "twoStepAuthenticatorReaddDesc": { "message": "Jeśli chcesz dodać inne urządzenie, poniżej znajdziesz kod QR (lub klucz) wymagany przez aplikację uwierzytelniającą." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "To okno zostanie automatycznie zamknięte za 5 sekund" }, + "youMayCloseThisWindow": { + "message": "Możesz zamknąć to okno" + }, "includeAllTeamsFeatures": { "message": "Wszystkie funkcje zespołów oraz:" }, @@ -8385,7 +8397,7 @@ "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": "Zidentyfikuj ryzyka bezpieczeństwa poprzez audyt dostępów członków" }, "onlyAvailableForEnterpriseOrganization": { "message": "Szybko przejrzyj dostęp członków do całej organizacji poprzez uaktualnienie do planu Enterprise." @@ -8396,15 +8408,11 @@ "exportClientReport": { "message": "Eksportuj raport klienta" }, - "invoiceNumberHeader": { - "message": "Numer faktury", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { - "message": "Member access" + "message": "Dostęp członków" }, "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": "Upewnij się, że członkowie mają dostęp do odpowiednich danych uwierzytelniających, a ich konta są bezpieczne. Użyj tego raportu, aby uzyskać dostęp do CSV z dostępem użytkownika i konfiguracją konta." }, "higherKDFIterations": { "message": "Wyższe wartości iteracji KDF mogą pomóc chronić Twoje hasło główne przed złamaniem przez atakującego." @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "Ta akcja usunie Twój dostęp do tego sekretu." + }, + "invoice": { + "message": "Faktura" + }, + "unassignedSeatsAvailable": { + "message": "Masz $SEATS$ nieprzypisanych miejsc.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Skontaktuj się z administratorem dostawcąy w celu zakupu dodatkowych miejsc." + }, + "open": { + "message": "Otwarta", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Niesciągalna", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Szczegóły klienta" + }, + "downloadCSV": { + "message": "Pobierz CSV" + }, + "billingHistoryDescription": { + "message": "Pobierz plik CSV, aby uzyskać dane klienta dla każdej daty rozliczeniowej. Proporcjonalne opłaty nie są uwzględnione w CSV i mogą różnić się od powiązanej faktury. Aby uzyskać najdokładniejsze dane rozliczeniowe, zapoznaj się z Twoimi miesięcznymi fakturami.", + "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." } } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index c3e6186a5b3..96e9380703c 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplicativo de autenticação" }, - "authenticatorAppDesc": { - "message": "Utilize um aplicativo de autenticação (tal como Authy ou Google Authenticator) para gerar códigos de verificação baseados no tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chave de segurança YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utilize uma YubiKey para acessar a sua conta. Funciona com YubiKey 4, 4 Nano, 4C, e dispositivos NEO." }, - "duoDesc": { - "message": "Verifique com o Duo Security utilizando o aplicativo Duo Mobile, SMS, chamada telefônica, ou chave de segurança U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Os códigos de verificação vão ser enviados por e-mail para você." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continuar" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Insira a sua senha mestra para modificar as configurações de login em duas etapas." }, - "twoStepAuthenticatorDesc": { - "message": "Siga estas etapas para configurar o login em duas etapas com um aplicativo autenticador:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Baixar um app autenticador de duas etapas" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Precisa de um aplicativo autenticador de duas etapas? Baixe um dos seguintes" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Dispositivos iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Dispositivos Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Dispositivos Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Esses aplicativos são os recomendados, no entanto, outros aplicativos de autenticação também irão funcionar." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Escaneie este código QR com o seu aplicativo de duas etapas" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Chave" }, - "twoStepAuthenticatorEnterCode": { - "message": "Insira o código de verificação de 6 dígitos resultante do aplicativo" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Caso você precise adicioná-lo a outro dispositivo, abaixo está o código QR (ou chave) exigido pelo aplicativo autenticador." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Esta janela será fechada automaticamente em 5 segundos" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Recursos para Todas as Equipes, além de:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Exportar relatório do cliente" }, - "invoiceNumberHeader": { - "message": "Número da fatura", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 17c38726856..41e4d66a9fa 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -344,7 +344,7 @@ "message": "Nome próprio" }, "middleName": { - "message": "Segundo nome" + "message": "Nome do meio" }, "lastName": { "message": "Apelido" @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplicação de autenticação" }, - "authenticatorAppDesc": { - "message": "Utilize uma aplicação de autenticação (como o Authy ou o Google Authenticator) para gerar códigos de verificação baseados no tempo.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Chave de segurança YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Utilize uma YubiKey para aceder à sua conta. Funciona com YubiKey série 4, série 5, e dispositivos NEO." + "message": "Utilize uma YubiKey para aceder à sua conta. Funciona com YubiKey 4, 4 Nano, 4C, e dispositivos NEO." }, - "duoDesc": { - "message": "Verifique com a Duo Security utilizando a aplicação Duo Mobile, SMS, chamada telefónica ou chave de segurança U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Os códigos de verificação ser-lhe-ão enviados por e-mail." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continuar" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Introduza a sua palavra-passe mestra para modificar as definições da verificação de dois passos." }, - "twoStepAuthenticatorDesc": { - "message": "Siga estes passos para ativar a verificação de dois passos com uma aplicação de autenticação:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Descarregue uma aplicação de autenticação de dois passos" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Precisa de uma aplicação de autenticação de dois passos? Descarregue uma das seguintes aplicações" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Dispositivos iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Dispositivos Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Dispositivos Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Estas aplicações são recomendadas, no entanto, outras aplicações de autenticação também funcionam." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Digitalize este código QR com a sua aplicação de autenticação" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Chave" }, - "twoStepAuthenticatorEnterCode": { - "message": "Introduza o código de confirmação de 6 dígitos indicado pela aplicação" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Caso necessite de o adicionar a outro dispositivo, segue-se o código QR (ou chave) exigido pela sua aplicação de autenticação." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Esta janela fechar-se-á automaticamente em 5 segundos" }, + "youMayCloseThisWindow": { + "message": "Pode fechar esta janela" + }, "includeAllTeamsFeatures": { "message": "Todas as funcionalidades de Equipas, mais:" }, @@ -7070,7 +7082,7 @@ "message": "Escreva ou selecione pessoas ou grupos" }, "projectServiceAccountsDescription": { - "message": "Conceder acesso a este projeto às contas de serviço." + "message": "Conceder às contas de serviço acesso a este projeto." }, "projectServiceAccountsSelectHint": { "message": "Escreva ou selecione contas de serviço" @@ -7889,7 +7901,7 @@ "message": "Os ajustes nos lugares serão refletidos no ciclo de faturação seguinte." }, "unassignedSeatsDescription": { - "message": "Lugares de subscrição não atribuídos" + "message": "Lugares não atribuídos" }, "purchaseSeatDescription": { "message": "Lugares adicionais adquiridos" @@ -8035,7 +8047,7 @@ "description": "Notifies that a machine account has been updated" }, "projectMachineAccountsDescription": { - "message": "Conceder acesso a este projeto às contas automáticas." + "message": "Conceder às contas automáticas acesso a este projeto." }, "projectMachineAccountsSelectHint": { "message": "Escreva ou selecione contas automáticas" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Exportar o relatório do cliente" }, - "invoiceNumberHeader": { - "message": "Número da fatura", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Acesso dos membros" }, @@ -8428,24 +8436,58 @@ } }, "providerReinstate": { - "message": " Contact Customer Support to reinstate your subscription." + "message": " Contacte o Apoio ao Cliente para restabelecer a sua subscrição." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Conceder a grupos ou pessoas acesso a este segredo. As permissões definidas para pessoas substituem as permissões definidas por grupos." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Adicione pessoas ou grupos para partilhar o acesso a este segredo" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Conceder às contas automáticas acesso a este segredo." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Adicionar contas automáticas para conceder acesso a este segredo" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Remover o acesso a este segredo" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Esta ação retirará o seu acesso a este segredo." + }, + "invoice": { + "message": "Fatura" + }, + "unassignedSeatsAvailable": { + "message": "Tem $SEATS$ lugares não atribuídos disponíveis.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contacte o administrador do seu fornecedor para adquirir lugares adicionais." + }, + "open": { + "message": "Aberta", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Incobrável", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Dados do cliente" + }, + "downloadCSV": { + "message": "Transferir CSV" + }, + "billingHistoryDescription": { + "message": "Transfira um CSV para obter os dados do cliente para cada data de faturação. As taxas rateadas não estão incluídas no CSV e podem variar em relação à fatura associada. Para obter os dados de faturação mais precisos, consulte as suas faturas mensais.", + "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." } } diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index cee0171ebe4..b595c722f6d 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplicația Autentificator" }, - "authenticatorAppDesc": { - "message": "Utilizați o aplicație de autentificare (cum ar fi Authy sau Google Authenticator) pentru a genera codurile de verificare bazate pe timp.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Cheie de securitate YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Utilizați un YubiKey pentru a vă accesa contul. Funcționează cu dispozitivele YubiKey serie 4, 5 și NEO." }, - "duoDesc": { - "message": "Verificați cu Duo Security utilizând aplicația Duo Mobile, SMS, apel telefonic sau cheia de securitate U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-mail" }, - "emailDesc": { - "message": "Codurile de verificare vor fi trimise prin e-mail." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continuare" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Introduceți parola principală pentru a modifica setările de autentificare în două etape." }, - "twoStepAuthenticatorDesc": { - "message": "Urmați acești pași pentru a configura autentificarea în două etape cu o aplicație de autentificare:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Descărcați o aplicație de autentificare în două etape" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Aveți nevoie de o aplicație de autentificare în două etape? Descărcați una dintre următoarele" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Dispozitive iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Dispozitive Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Dispozitive Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Aceste aplicații sunt recomandate, cu toate acestea, vor funcționa și alte aplicații de autentificare." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scanați acest cod QR cu aplicația dvs. de autentificare" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Cheie" }, - "twoStepAuthenticatorEnterCode": { - "message": "Introduceți codul de verificare din 6 cifre din aplicație" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Dacă trebuie să-l adăugați la un alt dispozitiv, mai jos este codul QR (sau cheia) cerut de aplicația dvs. de autentificare." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "Toate funcțiile planului Echipe, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index fb16fca4f06..95496763ae8 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Приложение-аутентификатор" }, - "authenticatorAppDesc": { - "message": "Используйте приложение-аутентификатор (например Authy или Google Authenticator) для создания кодов проверки на основе времени.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ безопасности YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Используйте YubiKey для доступа к аккаунту. Работает с устройствами YubiKey серий 4, 5 и NEO." }, - "duoDesc": { - "message": "Подтвердите при помощи Duo Security, используя приложение Duo Mobile, SMS, телефонный звонок или ключ безопасности U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Коды подтверждения будут отправлены вам по электронной почте." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Продолжить" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Для изменения настроек двухэтапной аутентификации введите мастер-пароль." }, - "twoStepAuthenticatorDesc": { - "message": "Выполните следующие шаги, чтобы настроить двухэтапную аутентификацию с помощью приложения-аутетификатора:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Загрузите приложение-аутентификатор" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Нужно приложение-аутентификатор? Загрузите одно из следующих" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Устройства iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Устройства Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Устройства Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Это рекомендуемые приложения, однако, будут работать и другие приложения-аутентификаторы." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Отсканируйте этот QR-код вашим приложением-аутентификатором" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Ключ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Введите полученный 6-значный код подтверждения из вашего приложения-аутентификатора" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Если вам нужно добавить его на другое устройство, ниже указан QR-код для приложения-аутентификатора." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Это окно автоматически закроется через 5 секунд" }, + "youMayCloseThisWindow": { + "message": "Можете закрыть это окно" + }, "includeAllTeamsFeatures": { "message": "Все возможности Teams, плюс:" }, @@ -7889,7 +7901,7 @@ "message": "Корректировка мест будет отражена в следующем расчетном цикле." }, "unassignedSeatsDescription": { - "message": "Нераспределенные места в соответствии с подпиской" + "message": "Назначенные места" }, "purchaseSeatDescription": { "message": "Приобретено дополнительных мест" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Экспорт отчета клиента" }, - "invoiceNumberHeader": { - "message": "Номер счета", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Доступ пользователей" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "Это действие удалит ваш доступ к этому секрету." + }, + "invoice": { + "message": "Счет" + }, + "unassignedSeatsAvailable": { + "message": "Неназначенных мест: $SEATS$.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Свяжитесь с администратором провайдера для покупки дополнительных мест." + }, + "open": { + "message": "Открыть", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Информация о клиенте" + }, + "downloadCSV": { + "message": "Скачать CSV" + }, + "billingHistoryDescription": { + "message": "Скачайте файл CSV, чтобы получить данные о клиенте за каждую расчетную дату. Пропорциональные расходы не включены в CSV и могут отличаться от привязанного счета. Для получения наиболее точной информации о счетах обратитесь к ежемесячным счетам.", + "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." } } diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index 0aa20614268..8af53721b52 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "වි-තැපෑල" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "ඉදිරියට" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index edcb04a59ce..3e81a768873 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Overovacia aplikácia" }, - "authenticatorAppDesc": { - "message": "Použite overovaciu aplikáciu (napríklad Authy alebo Google Authenticator) na generovanie časovo obmedzených overovacích kódov.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP bezpečnostný kľúč" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Použiť YubiKey pre prístup k vášmu účtu. Pracuje s YubiKey 4, 4 Nano, 4C a s NEO zariadeniami." }, - "duoDesc": { - "message": "Overiť s Duo Security použitím Duo Mobile aplikácie, SMS, telefonátu alebo U2F bezpečnostným kľúčom.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verifikačné kódy vám budú zaslané emailom." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Ďalej" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Zadajte vaše hlavné heslo ak chcete zmeniť nastavenia dvojstupňového prihlásenia." }, - "twoStepAuthenticatorDesc": { - "message": "Nasledujte tieto kroky ak chcete nastaviť dvojstupňové prihlásenie s autentifikačnou aplikáciou:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Stiahnite si autentifikačnú aplikáciu" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Potrebujete dvojstupňovú autentifikačnú aplikáciu? Stiahnite si následujúcu" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Zariadenia so systémom iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android zariadenia" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Zariadenia so systémom Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Odporúčame použiť tieto aplikácie, avšak aj iné autentifikačné aplikácie by mali fungovať." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Oskenujte QR kód s vašou autentifikačnou aplikáciou" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Kľúč" }, - "twoStepAuthenticatorEnterCode": { - "message": "Zadajte výsledný 6 miestny overovací kód z aplikácie" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "AK chcete pridať účet do ďalšieho zariadenia, nižšie je QR kód (alebo kľúč) ktorý požaduje vaša autentifikačná aplikácia." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "Toto okno môžete zavrieť" + }, "includeAllTeamsFeatures": { "message": "Všetky funkcie verzie pre Tímy, plus:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Exportovať klientský report" }, - "invoiceNumberHeader": { - "message": "Číslo faktúry", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Prístup člena" }, @@ -8431,21 +8439,55 @@ "message": " Ak chcete obnoviť vaše predplatné, kontaktujte zákaznícku podporu." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Povoliť skupinám alebo jednotlivcom prístup k tejto položke. Oprávnenie nastavené pre jednotlivcov majú prioritu pred oprávneniami nastavenými skupinou." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Pridať jednotlivcov alebo skupiny pre zdieľanie prístupu k tejto položke" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Povoľte služobným kontám prístup k tejto položke." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Pridajte služobné kontá pre povolenie prístupu k tejto položke" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Odstrániť prístup k tejto položke" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Táto akcia odstráni váš prístup k položke." + }, + "invoice": { + "message": "Faktúra" + }, + "unassignedSeatsAvailable": { + "message": "Máte k dispozícii $SEATS$ nepridelených sedení.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Kontaktujte správcu vášho poskytovateľa pre zakúpenie dodatočných sedení." + }, + "open": { + "message": "Otvorená", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Nevyberateľná", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Detail klienta" + }, + "downloadCSV": { + "message": "Stiahnuť CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index 8d9ec2be1cd..501d15cf89b 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplikacija za avtentikacijo" }, - "authenticatorAppDesc": { - "message": "Uporabite aplikacijo za avtentikacijo (npr. Authy ali Google Authenticator), ki za vas ustvarja kode z omejenim časom veljavnosti.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey varnostni ključ za enkratna gesla" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Uporabite YubiKey za dostop do svojega računa. Podprti so YubiKey serije 4, serije 5 in naprave NEO." }, - "duoDesc": { - "message": "Preverjajte z uporabo Duo Security, ki omogoča prijavo z Duo Mobile aplikacijo, SMS sporočilom, telefonskim klicem ali U2F varnostnim ključem.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-pošta" }, - "emailDesc": { - "message": "Potrditvene kode vam bodo posredovane po e-pošti." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Nadaljuj" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Za spremembno nastavitev dvostopenjske prijave vnesite glavno geslo." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS naprave" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android naprave" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows naprave" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Ključ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 47f294baa7d..1982666729b 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Апликација Аутентификатор" }, - "authenticatorAppDesc": { - "message": "Користите апликацију за аутентификацију (као што је Authy или Google Authenticator) за генерисање верификационих кодова.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Унесите кôд који генерише апликација за аутентификацију као што је Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP сигурносни кључ" + "yubiKeyTitleV2": { + "message": "Yubico OTP сигурносни кључ" }, "yubiKeyDesc": { "message": "Користите YubiKey за приступ налогу. Ради са YubiKey 4 и 5, и NEO уређаје." }, - "duoDesc": { - "message": "Провери са Duo Security користећи Duo Mobile апликацију, СМС, телефонски позив, или U2F кључ.", + "duoDescV2": { + "message": "Унесите кôд који је генерисао Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "Е-пошта" }, - "emailDesc": { - "message": "Верификациони кодови ће вам бити послати имејлом." + "emailDescV2": { + "message": "Унесите код послат на вашу е-пошту." }, "continue": { "message": "Настави" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Унесите главну лозинку да бисте изменили подешавања пријављивања у два корака." }, - "twoStepAuthenticatorDesc": { - "message": "Следите ове кораке за подешавање пријаве у два корака помоћу апликације за проверу аутентичности:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Преузмите апликацију за аутентификацију као што је" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Преузмите апликацију за аутентификацију у два корака" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Треба вам апликација за аутентификацију у два корака? Преузмите једну од следеће" + "twoStepAuthenticatorInstructionInfix2": { + "message": "или" }, - "iosDevices": { - "message": "iOS уређаји" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android уређаји" + "continueToExternalUrlTitle": { + "message": "Наставити на $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows уређаји" + "continueToExternalUrlDesc": { + "message": "Напуштате Bitwarden и покрећете спољне веб странице у новом прозору." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Ове апликације се препоручују, међутим, друге апликације за утврђивање аутентичности такође ће радити." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Наставити на bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Скенирајте овај QR код са апликацијом за идентификљцију" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Bitwarden Authenticator омогућава вам да чувате кључеве аутентификатора и генеришете ТОТП кодове за токове верификације у 2 корака. Сазнајте више на bitwarden.com." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Скенирајте КР кôд у наставку помоћу апликације за аутентификацију или унесите кључ." }, "key": { "message": "Кључ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Унесите резултирајући шестоцифрени код из апликације" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Верификациони кôд" }, "twoStepAuthenticatorReaddDesc": { "message": "У случају да га требате додати на други уређај, доле је КР код (или кључ) који захтева ваша апликација за аутентификацију." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Овај прозор ће се аутоматски затворити за 5 секунди" }, + "youMayCloseThisWindow": { + "message": "Можете затворити овај прозор" + }, "includeAllTeamsFeatures": { "message": "Све функције тима, плус:" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Извези извештај клијента" }, - "invoiceNumberHeader": { - "message": "Број фактуре", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Приступ чланова" }, @@ -8428,24 +8436,58 @@ } }, "providerReinstate": { - "message": " Contact Customer Support to reinstate your subscription." + "message": " Контактирајте корисничку подршку да бисте обновили претплату." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Одобрите групама или особама приступ овој тајни. Дозволе постављене за особе ће заменити дозволе које су поставиле групе." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Додајте особе или групе да бисте делили приступ овој тајни" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Одобрите налозима машине приступ овој тајни." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Додајте машинске налоге да бисте одобрили приступ овој тајни" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Уклоните приступ овој тајни" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Ова радња ће вам уклонити приступ овој тајни." + }, + "invoice": { + "message": "Фактура" + }, + "unassignedSeatsAvailable": { + "message": "Имат $SEATS$ доступна нераспоређена места.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Обратите се свом админ провајдеру да бисте купили додатна места." + }, + "open": { + "message": "Отвори", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Ненаплативо", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Детаљи клијента" + }, + "downloadCSV": { + "message": "Преузми ЦСВ" + }, + "billingHistoryDescription": { + "message": "Преузмите ЦСВ да бисте добили детаље о клијенту за сваки датум обрачуна. Пропорционални трошкови нису укључени у ЦСВ и могу се разликовати од повезане фактуре. За најтачније податке о обрачуну погледајте своје месечне фактуре.", + "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." } } diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index 90b71180d24..96b2df7ac5d 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Aplikacija za Autentifikaciju" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Nastavi" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Ključ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index ef536273dc3..3c348579784 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Autentiseringsapp" }, - "authenticatorAppDesc": { - "message": "Använd en autentiseringsapp (t.ex. Authy eller Google Authenticator) för att skapa tidsbaserade verifieringskoder.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP-säkerhetsnyckel" + "yubiKeyTitleV2": { + "message": "Yubico OTP-säkerhetsnyckel" }, "yubiKeyDesc": { "message": "Använd en YubiKey för att komma åt ditt konto. Fungerar med YubiKey 4-serien, 5-serien och NEO-enheter." }, - "duoDesc": { - "message": "Verifiera med Duo Security genom att använda Duo Mobile-appen, SMS, telefonsamtal eller en U2F-säkerhetsnyckel.", + "duoDescV2": { + "message": "Ange en kod som genererats av Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-post" }, - "emailDesc": { - "message": "Verifieringskoder kommer skickas till dig via e-post." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Fortsätt" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Ange ditt huvudlösenord för att ändra inställningarna för tvåstegsverifiering." }, - "twoStepAuthenticatorDesc": { - "message": "Följ dessa steg för att konfigurera tvåstegsverifiering med en autentiseringsapp:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Hämta en tvåstegsverifieringsapp" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Behöver du en tvåstegsverifieringsapp? Hämta en av följande" + "twoStepAuthenticatorInstructionInfix2": { + "message": "eller" }, - "iosDevices": { - "message": "iOS-enheter" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android-enheter" + "continueToExternalUrlTitle": { + "message": "Fortsätt till $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows-enheter" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Dessa appar rekommenderas, men även andra autentiseringsappar fungerar." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Fortsätt till bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Skanna denna QR-kod med din autentiseringsapp" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Nyckel" }, - "twoStepAuthenticatorEnterCode": { - "message": "Ange den 6-siffriga verifieringskoden från appen" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verifieringskod" }, "twoStepAuthenticatorReaddDesc": { "message": "Om du behöver lägga till den på en annan enhet, finns QR-koden (eller nyckeln) som krävs av din autentiseringsapp nedan." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "Du kan stänga detta fönster" + }, "includeAllTeamsFeatures": { "message": "Alla funktioner för team, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Exportera klientrapport" }, - "invoiceNumberHeader": { - "message": "Fakturanummer", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Medlemsåtkomst" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Faktura" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Ladda ner CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index 91fadde228a..c45fa99b2c0 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator app" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Continue" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index dee324171ac..7e1d530a578 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Authenticator App" }, - "authenticatorAppDesc": { - "message": "Use an authenticator app (such as Authy or Google Authenticator) to generate time-based verification codes.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP security key" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4 series, 5 series, and NEO devices." + "message": "Use a YubiKey 4, 5 or NEO device." }, - "duoDesc": { - "message": "Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -984,13 +984,13 @@ "message": "Use any FIDO U2F compatible security key to access your account." }, "u2fTitle": { - "message": "FIDO U2F security key" + "message": "FIDO U2F security a key" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Use your device's biometrics or a FIDO2 compatible security key." }, "webAuthnMigrated": { "message": "(Migrated from FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "อีเมล" }, - "emailDesc": { - "message": "Verification codes will be emailed to you." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "ดำเนินการต่อ" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Enter your master password to modify two-step login settings." }, - "twoStepAuthenticatorDesc": { - "message": "Follow these steps to set up two-step login with an authenticator app:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Download a two-step authenticator app" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Need a two-step authenticator app? Download one of the following" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS devices" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android devices" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows devices" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "These apps are recommended, however, other authenticator apps will also work." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Scan this QR code with your authenticator app" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Key" }, - "twoStepAuthenticatorEnterCode": { - "message": "Enter the resulting 6 digit verification code from the app" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "In case you need to add it to another device, below is the QR code (or key) required by your authenticator app." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index cbbdd9f0555..48996245cdf 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Kimlik doğrulama uygulaması" }, - "authenticatorAppDesc": { - "message": "Zamana dayalı doğrulama kodları oluşturmak için kimlik doğrulama uygulaması (örn. Authy veya Google Authenticator) kullanın.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP güvenlik anahtarı" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "Hesabınıza erişmek için YubiKey kullanabilirsiniz. YubiKey 4 serisi, 5 serisi ve NEO cihazlarıyla çalışır." }, - "duoDesc": { - "message": "Duo Security ile doğrulama için Duo Mobile uygulaması, SMS, telefon araması veya U2F güvenlik anahtarını kullanın.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "E-posta" }, - "emailDesc": { - "message": "Doğrulama kodları e-posta adresinize gönderilecek." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Devam" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "İki aşamalı giriş ayarlarını değiştirmek için ana parolanızı girin." }, - "twoStepAuthenticatorDesc": { - "message": "Kimlik doğrulama uygulamasıyla iki aşamalı girişi ayarlamak için aşağıdaki adımları izleyin:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "İki aşamalı kimlik doğrulama uygulamalarından birini indirin" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Kimlik doğrulama uygulamasına mı ihtiyacınız var? Aşağıdakilerden birini indirebilirsiniz" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS cihazları" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android cihazları" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows cihazları" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Bunlar bizim önerdiğimiz uygulamalar ama farklı kimlik doğrulama uygulamaları da kullanabilirsiniz." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Bu QR kodunu kimlik doğrulama uygulamanızla tarayın" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Anahtar" }, - "twoStepAuthenticatorEnterCode": { - "message": "Uygulamanın verdiği 6 basamaklı doğrulama kodunu girin" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Başka bir cihaza eklemeniz gerekirse kimlik doğrulama uygulamanıza aşağıdaki QR kodunu (veya anahtarı) verebilirsiniz." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Bu pencere 5 saniye içinde otomatik olarak kapanacaktır" }, + "youMayCloseThisWindow": { + "message": "Bu pencereyi kapatabilirsiniz" + }, "includeAllTeamsFeatures": { "message": "Ekip paketi özelliklerinin yanı sıra:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Fatura" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Açık", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 81b0ee8b8d6..03b574f63ee 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Програма автентифікації" }, - "authenticatorAppDesc": { - "message": "Використовуйте програму автентифікації (наприклад, Authy або Google Authenticator), щоб генерувати тимчасові коди підтвердження.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Введіть код, згенерований програмою для автентифікації, як-от Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Ключ безпеки YubiKey OTP" + "yubiKeyTitleV2": { + "message": "Ключ безпеки Yubico OTP" }, "yubiKeyDesc": { - "message": "Використовуйте YubiKey для доступу до облікового запису. Працює з YubiKey серії 4, 5, а також пристроями NEO." + "message": "Використовуйте YubiKey 4, 5, або пристрій NEO." }, - "duoDesc": { - "message": "Авторизуйтесь за допомогою Duo Security з використанням мобільного додатку Duo Mobile, SMS, телефонного виклику, або ключа безпеки U2F.", + "duoDescV2": { + "message": "Введіть код, згенерований Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -987,10 +987,10 @@ "message": "Ключ безпеки FIDO U2F" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Ключ доступу" }, "webAuthnDesc": { - "message": "Використовуйте будь-який ключ безпеки WebAuthn для доступу до сховища." + "message": "Використовуйте біометрію вашого пристрою або сумісний ключ безпеки FIDO2." }, "webAuthnMigrated": { "message": "(Перенесено з FIDO)" @@ -998,8 +998,8 @@ "emailTitle": { "message": "Е-пошта" }, - "emailDesc": { - "message": "Коди підтвердження будуть надсилатися на вашу пошту." + "emailDescV2": { + "message": "Введіть код, надісланий вам електронною поштою." }, "continue": { "message": "Продовжити" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Введіть головний пароль, щоб змінити налаштування двоетапної перевірки." }, - "twoStepAuthenticatorDesc": { - "message": "Налаштуйте двоетапну перевірку за допомогою програми автентифікації:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Завантажте програму для автентифікації, як от" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Завантажте програму автентифікації для двоетапної перевірки" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Необхідна програма автентифікації для двоетапної перевірки? Завантажте одну з таких" + "twoStepAuthenticatorInstructionInfix2": { + "message": "або" }, - "iosDevices": { - "message": "Пристрої iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Пристрої Android" + "continueToExternalUrlTitle": { + "message": "Продовжити на $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Пристрої Windows" + "continueToExternalUrlDesc": { + "message": "Зараз ви перейдете з Bitwarden до вебсайту в новому вікні." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Ці програми є рекомендованими, однак ви можете використовувати й інші." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Продовжити на bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Скануйте цей QR-код за допомогою програми автентифікації" + "twoStepContinueToBitwardenUrlDesc": { + "message": "Bitwarden Authenticator дозволяє зберігати ключі авторизації та генерувати одноразові коди TOTP для двоетапної перевірки. Дізнайтеся більше про це на вебсайті bitwarden.com." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Скануйте зазначений нижче QR-код за допомогою програми для автентифікації або введіть ключ." }, "key": { "message": "Ключ" }, - "twoStepAuthenticatorEnterCode": { - "message": "Введіть отриманий в програмі 6-значний код підтвердження" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Код підтвердження" }, "twoStepAuthenticatorReaddDesc": { "message": "Якщо вам необхідно додати інший пристрій, скануйте зазначений нижче QR-код (або введіть ключ) для вашої програми автентифікації." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "Це вікно автоматично закриється через 5 секунд" }, + "youMayCloseThisWindow": { + "message": "Можете закрити це вікно" + }, "includeAllTeamsFeatures": { "message": "Усі функції команд, плюс:" }, @@ -7889,7 +7901,7 @@ "message": "Скориговані місця будуть відображені в наступному платіжному циклі." }, "unassignedSeatsDescription": { - "message": "Непризначені місця передплати" + "message": "Непризначені місця" }, "purchaseSeatDescription": { "message": "Додаткові придбані місця" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Експортувати звіт клієнта" }, - "invoiceNumberHeader": { - "message": "Номер рахунку", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Доступ учасників" }, @@ -8431,21 +8439,55 @@ "message": " Зверніться до служби підтримки для відновлення передплати." }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "Надайте групам або людям доступ до цього секрету. Дозволи, надані користувачам, перевизначать дозволи, встановлені для груп." }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "Додайте людей або групи, щоб поділитися доступом до цього секрету" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "Надайте машинним обліковим записам доступ до цього секрету." }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "Додайте машинні облікові записи для надання доступу до цього секрету" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "Скасувати доступ до цього секрету" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "Ця дія призведе до вилучення вашого доступу до цього секрету." + }, + "invoice": { + "message": "Рахунок" + }, + "unassignedSeatsAvailable": { + "message": "У вас доступно $SEATS$ непризначених місць.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Зверніться до адміністратора вашого провайдера для придбання додаткових місць." + }, + "open": { + "message": "Відкрито", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Не збирається", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Подробиці клієнта" + }, + "downloadCSV": { + "message": "Завантажити CSV" + }, + "billingHistoryDescription": { + "message": "Завантажте CSV для отримання клієнтських даних для кожної платіжної дати. Пропорційні витрати не включаються до CSV і можуть відрізнятися від пов'язаного рахунка. Для отримання найточніших даних щодо оплати, перегляньте щомісячні рахунки.", + "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." } } diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index 8bca2f71749..f1002d58281 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "Ứng dụng xác thực" }, - "authenticatorAppDesc": { - "message": "Sử dụng một ứng dụng xác thực (chẳng hạn như Authy hoặc Google Authenticator) để tạo các mã xác thực thời gian thực.", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "Mật khẩu OTP YubiKey" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "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." }, - "duoDesc": { - "message": "Xác minh với Duo Security dùng ứng dụng Duo Mobile, SMS, điện thoại, hoặc mật khẩu U2F.", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -987,7 +987,7 @@ "message": "Mật khẩu FIDO U2F" }, "webAuthnTitle": { - "message": "FIDO2 WebAuthn" + "message": "Passkey" }, "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." @@ -998,8 +998,8 @@ "emailTitle": { "message": "Email" }, - "emailDesc": { - "message": "Mã xác minh sẽ được gửi qua email cho bạn." + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "Tiếp tục" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "Vui lòng nhập mật khẩu chính để chỉnh sửa cài đặt đăng nhập hai bước." }, - "twoStepAuthenticatorDesc": { - "message": "Làm theo hướng dẫn để thiết lập đăng nhập 2 bước bằng ứng dụng:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "Tải về ứng dụng xác thực hai bước" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "Cần ứng dụng xác thực hai bước? Tải theo danh sách sau" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "Thiết bị iOS" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Thiết bị Android" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Thiết bị Windows" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "Những ứng dụng xác thực sau đây được khuyên dùng, nhưng những cái khác cũng ok." + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "Quét mã QR bằng ứng dụng xác thực" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "Khóa" }, - "twoStepAuthenticatorEnterCode": { - "message": "Vui lòng nhập mã 6 chữ số được tạo từ ứng dụng xác thực" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "Trong trường hợp bạn cần thêm thiết bị khác, ở dưới là mã QR (hoặc khóa) được yêu cầu bởi ứng dụng xác thực." @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "All Teams features, plus:" }, @@ -7889,7 +7901,7 @@ "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned subscription seats" + "message": "Unassigned seats" }, "purchaseSeatDescription": { "message": "Additional seats purchased" @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "Export client report" }, - "invoiceNumberHeader": { - "message": "Invoice number", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "Member access" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 721e6542df0..0889c924a48 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -717,7 +717,7 @@ "message": "设置强密码" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "通过设置密码完成账户的创建" + "message": "设置密码以完成账户的创建" }, "newAroundHere": { "message": "初来乍到吗?" @@ -768,7 +768,7 @@ "message": "主密码提示" }, "masterPassHintText": { - "message": "如果您忘记了密码,可以将密码提示发送到您的电子邮箱。$CURRENT$ / $MAXIMUM$ 最大字符数。", + "message": "如果您忘记了密码,可以发送密码提示到您的电子邮箱。$CURRENT$ / 最多 $MAXIMUM$ 个字符。", "placeholders": { "current": { "content": "$1", @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "验证器 App" }, - "authenticatorAppDesc": { - "message": "使用验证器 App(例如 Authy 或 Google Authenticator)来生成基于时间的验证码。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 安全钥匙" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "使用 YubiKey 来访问您的账户。支持 YubiKey 4 系列、5 系列以及 NEO 设备。" }, - "duoDesc": { - "message": "使用 Duo Security 的 Duo 移动应用、短信、电话或 U2F 安全钥匙来进行验证。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "电子邮件" }, - "emailDesc": { - "message": "验证码将会发送到您的电子邮箱。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "继续" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "输入您的主密码以修改两步登录设置。" }, - "twoStepAuthenticatorDesc": { - "message": "按照以下步骤,设置使用验证器 App 的两步登录:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "下载两步登录验证器 App" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "需要两步登录验证器 App 吗?下载以下其中一个:" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS 设备" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "安卓设备" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows 设备" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "推荐这些 App,当然,您也可以使用其它验证器 App。" + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "使用您的验证器 App 扫描这个二维码" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "密钥" }, - "twoStepAuthenticatorEnterCode": { - "message": "输入 App 中的 6 位数验证码" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "如果您要把它添加到其他设备,下面是您的验证器 App 所需要的二维码(或密钥)。" @@ -2111,7 +2120,7 @@ "message": "未来会增加更多高级功能。敬请期待!" }, "premiumPrice": { - "message": "每年只需 $PRICE$ !", + "message": "只需 $PRICE$ /年!", "placeholders": { "price": { "content": "$1", @@ -2142,7 +2151,7 @@ "message": "高级会员" }, "premiumAccessDesc": { - "message": "您可以为您的组织所有成员添加高级访问权限,只需 $PRICE$ / 每 $INTERVAL$ 。", + "message": "您可以为您的组织所有成员添加高级访问权限,只需 $PRICE$ /$INTERVAL$ 。", "placeholders": { "price": { "content": "$1", @@ -2161,7 +2170,7 @@ "message": "# GB 附加存储" }, "additionalStorageIntervalDesc": { - "message": "您的计划包含 $SIZE$ 的加密存储空间。您也可以以 $PRICE$ 每 GB 每 $INTERVAL$ 购买附加存储。", + "message": "您的计划包含 $SIZE$ 的加密存储空间。您也可以以每 GB $PRICE$ /$INTERVAL$ 购买附加存储。", "placeholders": { "size": { "content": "$1", @@ -2443,7 +2452,7 @@ "message": "# 用户席位" }, "userSeatsAdditionalDesc": { - "message": "您的计划包含 $BASE_SEATS$ 个用户席位。您也可以以 $SEAT_PRICE$ 每用户每月购买附加用户。", + "message": "您的计划包含 $BASE_SEATS$ 个用户席位。您也可以以每用户 $SEAT_PRICE$ /月购买附加用户。", "placeholders": { "base_seats": { "content": "$1", @@ -2463,7 +2472,7 @@ "description": "Free as in 'free beer'." }, "planDescFree": { - "message": "适用于测试或个人用户与 $COUNT$ 位其他用户共享。", + "message": "适用于测试或与 $COUNT$ 位其他用户共享的个人用户。", "placeholders": { "count": { "content": "$1", @@ -2508,7 +2517,7 @@ "message": "附加用户" }, "costPerUser": { - "message": "每位用户 $COST$", + "message": "每用户 $COST$", "placeholders": { "cost": { "content": "$1", @@ -2820,7 +2829,7 @@ "message": "全部" }, "addAccess": { - "message": "Add Access" + "message": "添加访问权限" }, "addAccessFilter": { "message": "Add Access Filter" @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "此窗口将在 5 秒后自动关闭" }, + "youMayCloseThisWindow": { + "message": "您可以关闭此窗口" + }, "includeAllTeamsFeatures": { "message": "所有团队版功能,以及:" }, @@ -7573,7 +7585,7 @@ } }, "additionalServiceAccountCost": { - "message": "附加服务账户 $COST$ 每月", + "message": "附加服务账户 $COST$ /月", "placeholders": { "cost": { "content": "$1", @@ -7600,7 +7612,7 @@ } }, "addAdditionalServiceAccounts": { - "message": "您也可以以 $COST$ 每月购买附加服务账户。", + "message": "您也可以以 $COST$ /月购买附加服务账户。", "placeholders": { "cost": { "content": "$1", @@ -7889,7 +7901,7 @@ "message": "席位的调整将反映在下一个计费周期中。" }, "unassignedSeatsDescription": { - "message": "未分配的订阅席位" + "message": "未分配的席位" }, "purchaseSeatDescription": { "message": "已购买附加席位" @@ -8071,7 +8083,7 @@ } }, "additionalMachineAccountCost": { - "message": "附加机器账户 $COST$ 每月", + "message": "附加机器账户 $COST$ /月", "placeholders": { "cost": { "content": "$1", @@ -8092,7 +8104,7 @@ } }, "addAdditionalMachineAccounts": { - "message": "您也可以以 $COST$ 每月购买附加机器账户。", + "message": "您也可以以 $COST$ /月购买附加机器账户。", "placeholders": { "cost": { "content": "$1", @@ -8242,7 +8254,7 @@ "message": "35% 折扣" }, "monthPerMember": { - "message": "month per member" + "message": "每成员 /月" }, "seats": { "message": "席位" @@ -8396,18 +8408,14 @@ "exportClientReport": { "message": "导出客户报告" }, - "invoiceNumberHeader": { - "message": "账单编号", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "成员访问权限" }, "memberAccessReportDesc": { - "message": "确保成员能够访问正确的凭据,以及他们的账户是安全的。使用此报告获取包含会员访问权限和账户配置的 CSV 文件 。" + "message": "确保成员具有对合适的凭据的访问权限,以及他们的账户是安全的。使用此报告获取包含会员访问权限和账户配置的 CSV 文件 。" }, "higherKDFIterations": { - "message": "更高的 KDF 迭代可以保护您的主密码不被攻击者暴力破解。" + "message": "更高的 KDF 迭代可以帮助保护您的主密码免遭攻击者的暴力破解。" }, "incrementsOf100,000": { "message": "100,000 增量" @@ -8431,21 +8439,55 @@ "message": " 联系客户支持恢复您的订阅。" }, "secretPeopleDescription": { - "message": "Grant groups or people access to this secret. Permissions set for people will override permissions set by groups." + "message": "授予群组或人员对此机密的访问权限。为人员设置的权限将覆盖群组设置的权限。" }, "secretPeopleEmptyMessage": { - "message": "Add people or groups to share access to this secret" + "message": "添加人员或群组以共享此机密的访问权限" }, "secretMachineAccountsDescription": { - "message": "Grant machine accounts access to this secret." + "message": "授予机器账户对此机密的访问权限。" }, "secretMachineAccountsEmptyMessage": { - "message": "Add machine accounts to grant access to this secret" + "message": "添加机器账户以授予对此机密的访问权限" }, "smAccessRemovalWarningSecretTitle": { - "message": "Remove access to this secret" + "message": "移除对此机密的访问权限" }, "smAccessRemovalSecretMessage": { - "message": "This action will remove your access to this secret." + "message": "此操作将移除您对此机密的访问权限。" + }, + "invoice": { + "message": "账单" + }, + "unassignedSeatsAvailable": { + "message": "您有 $SEATS$ 个未分配的席位可用。", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "请联系您的提供商管理员购买附加席位。" + }, + "open": { + "message": "打开", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "无法收集", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "客户详细信息" + }, + "downloadCSV": { + "message": "下载 CSV" + }, + "billingHistoryDescription": { + "message": "下载 CSV 以获取每个计费日期的客户详细信息。按比例分摊的费用不包含在此 CSV 中,并且可能与链接的账单不同。如需获取最准确的计费详细信息,请参阅您的月度账单。", + "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." } } diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index 359b9ccf058..73a2e257e28 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -962,18 +962,18 @@ "authenticatorAppTitle": { "message": "驗證器應用程式" }, - "authenticatorAppDesc": { - "message": "使用驗證器應用程式 (如 Authy 或 Google Authenticator) 產生基於時間的驗證碼。", - "description": "'Authy' and 'Google Authenticator' are product names and should not be translated." + "authenticatorAppDescV2": { + "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, - "yubiKeyTitle": { - "message": "YubiKey OTP 安全鑰匙" + "yubiKeyTitleV2": { + "message": "Yubico OTP security key" }, "yubiKeyDesc": { "message": "使用 YubiKey 存取您的帳戶。支援 YubiKey 4 系列、5 系列以及 NEO 裝置。" }, - "duoDesc": { - "message": "使用 Duo Security 的 Duo Mobile 程式、SMS 、撥打電話或 U2F 安全鑰匙進行驗證。", + "duoDescV2": { + "message": "Enter a code generated by Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { @@ -998,8 +998,8 @@ "emailTitle": { "message": "電子郵件" }, - "emailDesc": { - "message": "使用電子郵件傳送驗證碼給您。" + "emailDescV2": { + "message": "Enter a code sent to your email." }, "continue": { "message": "繼續" @@ -1639,35 +1639,44 @@ "twoStepLoginAuthDesc": { "message": "輸入您的主密碼以修改兩步驟登入設定。" }, - "twoStepAuthenticatorDesc": { - "message": "請依照下列步驟設定使用驗證器應用程式的兩步驟登入:" + "twoStepAuthenticatorInstructionPrefix": { + "message": "Download an authenticator app such as" }, - "twoStepAuthenticatorDownloadApp": { - "message": "下載兩步驟驗證器應用程式" + "twoStepAuthenticatorInstructionInfix1": { + "message": "," }, - "twoStepAuthenticatorNeedApp": { - "message": "需要驗證器應用程式嗎?您可以下載以下應用程式:" + "twoStepAuthenticatorInstructionInfix2": { + "message": "or" }, - "iosDevices": { - "message": "iOS 裝置" + "twoStepAuthenticatorInstructionSuffix": { + "message": "." }, - "androidDevices": { - "message": "Android 裝置" + "continueToExternalUrlTitle": { + "message": "Continue to $URL$?", + "placeholders": { + "url": { + "content": "$1", + "example": "bitwarden.com" + } + } }, - "windowsDevices": { - "message": "Windows 裝置" + "continueToExternalUrlDesc": { + "message": "You are leaving Bitwarden and launching an external website in a new window." }, - "twoStepAuthenticatorAppsRecommended": { - "message": "推薦使用下列的應用程式,您也可使用其他驗證器應用程式。" + "twoStepContinueToBitwardenUrlTitle": { + "message": "Continue to bitwarden.com?" }, - "twoStepAuthenticatorScanCode": { - "message": "使用您的驗證器應用程式掃描此 QR Code" + "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." + }, + "twoStepAuthenticatorScanCodeV2": { + "message": "Scan the QR code below with your authenticator app or enter the key." }, "key": { "message": "金鑰" }, - "twoStepAuthenticatorEnterCode": { - "message": "請輸入應用程式產生的 6 位數驗證碼" + "twoStepAuthenticatorEnterCodeV2": { + "message": "Verification code" }, "twoStepAuthenticatorReaddDesc": { "message": "若您需要將其加入其他裝置,以下是您的驗證器應用程式所需要的 QR Code(或金鑰)。" @@ -4151,6 +4160,9 @@ "thisWindowWillCloseIn5Seconds": { "message": "This window will automatically close in 5 seconds" }, + "youMayCloseThisWindow": { + "message": "You may close this window" + }, "includeAllTeamsFeatures": { "message": "包含所有團隊版功能" }, @@ -8396,10 +8408,6 @@ "exportClientReport": { "message": "匯出用戶端報告" }, - "invoiceNumberHeader": { - "message": "單據號碼", - "description": "A table header for an invoice's number" - }, "memberAccessReport": { "message": "成員存取" }, @@ -8447,5 +8455,39 @@ }, "smAccessRemovalSecretMessage": { "message": "This action will remove your access to this secret." + }, + "invoice": { + "message": "Invoice" + }, + "unassignedSeatsAvailable": { + "message": "You have $SEATS$ unassigned seats available.", + "placeholders": { + "seats": { + "content": "$1", + "example": "10" + } + }, + "description": "A message showing how many unassigned seats are available for a provider." + }, + "contactYourProviderForAdditionalSeats": { + "message": "Contact your provider admin to purchase additional seats." + }, + "open": { + "message": "Open", + "description": "The status of an invoice." + }, + "uncollectible": { + "message": "Uncollectible", + "description": "The status of an invoice." + }, + "clientDetails": { + "message": "Client details" + }, + "downloadCSV": { + "message": "Download CSV" + }, + "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.", + "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." } } From 3a3ff432b2456925a9b118492759641ca9f0e6ba Mon Sep 17 00:00:00 2001 From: Addison Beck Date: Fri, 28 Jun 2024 10:59:28 -0400 Subject: [PATCH 034/130] Update the README to mention the discrepancy with homebrew (#9856) * Update the README to mention the discrepancy with homebrew * Update copy --- apps/cli/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/cli/README.md b/apps/cli/README.md index b2d87ebaf91..e00b9a345d2 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -41,6 +41,9 @@ We provide natively packaged versions of the CLI for each platform which have no ```bash brew install bitwarden-cli ``` + > ⚠️ The homebrew version is not recommended for all users. + > + > Homebrew pulls the CLI's GPL build and does not include device approval commands for Enterprise SSO customers. - [Snap](https://snapcraft.io/bw) ```bash sudo snap install bw From a613d9c26848bcaa41f4568da5493f8236fbc808 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:41:17 +0200 Subject: [PATCH 035/130] [PM-8397] Make vault timeout input standalone (#9366) * Move vault-timeout-input to @bitwarden/auth/angular Move vault-timeout-input.component.ts to @bitwarden/auth/angular/vault-timeout-input Expose via barrel file Fix imports on clients * Add dependencies to package.json Not necessary right now, but good practice for once we move to building each package independently * Make VaultTimeoutInputComponent a standalone component * Update selector to present team ownership * Use new standalone on web Move vault-timeout-input.component.html to @bitwarden/auth/angular/vault-timeout-input/ Delete old vault-timeout-input.component on web Register new component on loose-components-module Update used selector in preferences.component * Remove unneeded export of VaultTimeoutInputComponent --------- Co-authored-by: Daniel James Smith --- .../settings/vault-timeout-input.component.ts | 2 +- .../accounts/vault-timeout-input.component.ts | 2 +- .../app/settings/preferences.component.html | 4 +-- .../settings/vault-timeout-input.component.ts | 22 --------------- .../src/app/shared/loose-components.module.ts | 5 ++-- libs/auth/package.json | 5 ++++ libs/auth/src/angular/index.ts | 1 + .../vault-timeout-input.component.html | 0 .../vault-timeout-input.component.ts | 27 +++++++++++++++++-- 9 files changed, 37 insertions(+), 31 deletions(-) delete mode 100644 apps/web/src/app/settings/vault-timeout-input.component.ts rename {apps/web/src/app/settings => libs/auth/src/angular/vault-timeout-input}/vault-timeout-input.component.html (100%) rename libs/{angular/src/components/settings => auth/src/angular/vault-timeout-input}/vault-timeout-input.component.ts (89%) diff --git a/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts b/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts index 75c3c9e9e0e..c56e6578a0b 100644 --- a/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts +++ b/apps/browser/src/auth/popup/settings/vault-timeout-input.component.ts @@ -1,7 +1,7 @@ import { Component } from "@angular/core"; import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from "@angular/forms"; -import { VaultTimeoutInputComponent as VaultTimeoutInputComponentBase } from "@bitwarden/angular/components/settings/vault-timeout-input.component"; +import { VaultTimeoutInputComponent as VaultTimeoutInputComponentBase } from "@bitwarden/auth/angular"; @Component({ selector: "app-vault-timeout-input", diff --git a/apps/desktop/src/app/accounts/vault-timeout-input.component.ts b/apps/desktop/src/app/accounts/vault-timeout-input.component.ts index 75c3c9e9e0e..c56e6578a0b 100644 --- a/apps/desktop/src/app/accounts/vault-timeout-input.component.ts +++ b/apps/desktop/src/app/accounts/vault-timeout-input.component.ts @@ -1,7 +1,7 @@ import { Component } from "@angular/core"; import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from "@angular/forms"; -import { VaultTimeoutInputComponent as VaultTimeoutInputComponentBase } from "@bitwarden/angular/components/settings/vault-timeout-input.component"; +import { VaultTimeoutInputComponent as VaultTimeoutInputComponentBase } from "@bitwarden/auth/angular"; @Component({ selector: "app-vault-timeout-input", diff --git a/apps/web/src/app/settings/preferences.component.html b/apps/web/src/app/settings/preferences.component.html index 0fe96a69ed3..876c5d3bdea 100644 --- a/apps/web/src/app/settings/preferences.component.html +++ b/apps/web/src/app/settings/preferences.component.html @@ -17,12 +17,12 @@ {{ "vaultTimeoutActionPolicyInEffect" | i18n: (policy.action | i18n) }} - - + Date: Fri, 28 Jun 2024 14:57:32 -0500 Subject: [PATCH 036/130] [PM-9342] Inline menu does not show on username field for a form that has a password field with an invalid autocomplete value (#9860) * [PM-9342] Inline menu does not show on username field for a form that has a password field with an invalid autocomplete value * [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-9342] Adding feedback from code review --- ...e-menu-field-qualification.service.spec.ts | 82 +++++++++++++--- ...inline-menu-field-qualification.service.ts | 93 +++++++++++++++++-- 2 files changed, 151 insertions(+), 24 deletions(-) diff --git a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.spec.ts b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.spec.ts index 2942ba545ea..0f95cd527ee 100644 --- a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.spec.ts +++ b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.spec.ts @@ -34,10 +34,23 @@ describe("InlineMenuFieldQualificationService", () => { ); }); + it("has a keyword value that indicates the field is for a create account form", () => { + const field = mock({ + type: "password", + placeholder: "create account password", + autoCompleteType: "", + }); + + expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe( + false, + ); + }); + it("has a type that is an excluded type", () => { AutoFillConstants.ExcludedAutofillLoginTypes.forEach((excludedType) => { const field = mock({ type: excludedType, + autoCompleteType: "", }); expect( @@ -53,6 +66,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlID: index === 0 ? attribute : "", htmlName: index === 1 ? attribute : "", placeholder: index > 1 ? attribute : "", + autoCompleteType: "", }); expect( @@ -67,6 +81,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlID: "not-password", htmlName: "not-password", placeholder: "not-password", + autoCompleteType: "", }); expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe( @@ -80,6 +95,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlID: "something-else", htmlName: "something-else", placeholder: "something-else", + autoCompleteType: "", }); expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe( @@ -93,6 +109,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlID: "search", htmlName: "something-else", placeholder: "something-else", + autoCompleteType: "", }); expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe( @@ -112,12 +129,14 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "user-password", placeholder: "user-password", form: "", + autoCompleteType: "", }); const secondField = mock({ type: "password", htmlID: "some-other-password", htmlName: "some-other-password", placeholder: "some-other-password", + autoCompleteType: "", }); pageDetails.fields = [field, secondField]; @@ -133,18 +152,21 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "user-password", placeholder: "user-password", form: "", + autoCompleteType: "", }); const usernameField = mock({ type: "text", htmlID: "user-username", htmlName: "user-username", placeholder: "user-username", + autoCompleteType: "", }); const secondUsernameField = mock({ type: "text", htmlID: "some-other-user-username", htmlName: "some-other-user-username", placeholder: "some-other-user-username", + autoCompleteType: "", }); pageDetails.fields = [field, usernameField, secondUsernameField]; @@ -186,6 +208,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "user-password", placeholder: "user-password", form: "validFormId", + autoCompleteType: "", }); const secondField = mock({ type: "password", @@ -193,6 +216,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "some-other-password", placeholder: "some-other-password", form: "validFormId", + autoCompleteType: "", }); pageDetails.fields = [field, secondField]; @@ -218,12 +242,35 @@ describe("InlineMenuFieldQualificationService", () => { ); }); + it("is structured on a page with a single set of username and password fields", () => { + const field = mock({ + type: "password", + htmlID: "user-password", + htmlName: "user-password", + placeholder: "user-password", + autoCompleteType: "", + }); + const usernameField = mock({ + type: "text", + htmlID: "user-username", + htmlName: "user-username", + placeholder: "user-username", + autoCompleteType: "", + }); + pageDetails.fields = [field, usernameField]; + + expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe( + true, + ); + }); + it("has a type of `text` with an attribute that indicates the field is a password field", () => { const field = mock({ type: "text", htmlID: null, htmlName: "user-password", placeholder: "user-password", + autoCompleteType: "", }); expect(inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails)).toBe( @@ -247,6 +294,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlID: "user-username", htmlName: "user-username", placeholder: "user-username", + autoCompleteType: "", }); pageDetails.fields = [field, usernameField]; @@ -273,6 +321,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "user-password", placeholder: "user-password", form: "validFormId", + autoCompleteType: "", }); const secondPasswordField = mock({ type: "password", @@ -280,6 +329,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "some-other-password", placeholder: "some-other-password", form: "anotherFormId", + autoCompleteType: "", }); const usernameField = mock({ type: "text", @@ -287,6 +337,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "user-username", placeholder: "user-username", form: "validFormId", + autoCompleteType: "", }); pageDetails.fields = [field, secondPasswordField, usernameField]; @@ -310,6 +361,7 @@ describe("InlineMenuFieldQualificationService", () => { htmlName: "some-other-password", placeholder: "some-other-password", form: "anotherFormId", + autoCompleteType: "", }); pageDetails.fields = [field, secondPasswordField]; @@ -347,21 +399,23 @@ describe("InlineMenuFieldQualificationService", () => { }); }); - ["new", "change", "neue", "ändern"].forEach((keyword) => { - it(`has a keyword of ${keyword} that indicates a 'new or changed' username is being filled`, () => { - const field = mock({ - type: "text", - autoCompleteType: "", - htmlID: "user-username", - htmlName: "user-username", - placeholder: `${keyword} username`, - }); + ["new", "change", "neue", "ändern", "register", "create", "registration"].forEach( + (keyword) => { + it(`has a keyword of ${keyword} that indicates a 'new or changed' username is being filled`, () => { + const field = mock({ + type: "text", + autoCompleteType: "", + htmlID: "user-username", + htmlName: "user-username", + placeholder: `${keyword} username`, + }); - expect( - inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails), - ).toBe(false); - }); - }); + expect( + inlineMenuFieldQualificationService.isFieldForLoginForm(field, pageDetails), + ).toBe(false); + }); + }, + ); describe("does not have a parent form element", () => { beforeEach(() => { diff --git a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts index 582f8889daa..7bc027b392c 100644 --- a/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts +++ b/apps/browser/src/autofill/services/inline-menu-field-qualification.service.ts @@ -14,9 +14,18 @@ export class InlineMenuFieldQualificationService private usernameAutocompleteValues = new Set(["username", "email"]); private fieldIgnoreListString = AutoFillConstants.FieldIgnoreList.join(","); private passwordFieldExcludeListString = AutoFillConstants.PasswordFieldExcludeList.join(","); + private currentPasswordAutocompleteValues = new Set(["current-password"]); + private newPasswordAutoCompleteValues = new Set(["new-password"]); private autofillFieldKeywordsMap: WeakMap = new WeakMap(); private autocompleteDisabledValues = new Set(["off", "false"]); private newFieldKeywords = new Set(["new", "change", "neue", "ändern"]); + private accountCreationFieldKeywords = new Set([ + "register", + "registration", + "create", + "confirm", + ...this.newFieldKeywords, + ]); private inlineMenuFieldQualificationFlagSet = false; constructor() { @@ -62,7 +71,12 @@ export class InlineMenuFieldQualificationService ): boolean { // If the provided field is set with an autocomplete value of "current-password", we should assume that // the page developer intends for this field to be interpreted as a password field for a login form. - if (field.autoCompleteType === "current-password") { + if ( + this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.currentPasswordAutocompleteValues, + ) + ) { return true; } @@ -95,7 +109,11 @@ export class InlineMenuFieldQualificationService // If a single username field or less is present on the page, then we can assume that the // provided field is for a login form. This will only be the case if the field does not // explicitly have its autocomplete attribute set to "off" or "false". - return !this.autocompleteDisabledValues.has(field.autoCompleteType); + + return !this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.autocompleteDisabledValues, + ); } // If the field has a form parent and there are multiple visible password fields @@ -117,7 +135,10 @@ export class InlineMenuFieldQualificationService // If the field has a form parent and no username field exists and the field has an // autocomplete attribute set to "off" or "false", this is not a password field - return !this.autocompleteDisabledValues.has(field.autoCompleteType); + return !this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.autocompleteDisabledValues, + ); } /** @@ -132,7 +153,9 @@ export class InlineMenuFieldQualificationService ): boolean { // If the provided field is set with an autocomplete of "username", we should assume that // the page developer intends for this field to be interpreted as a username field. - if (this.usernameAutocompleteValues.has(field.autoCompleteType)) { + if ( + this.fieldContainsAutocompleteValues(field.autoCompleteType, this.usernameAutocompleteValues) + ) { const newPasswordFieldsInPageDetails = pageDetails.fields.filter(this.isNewPasswordField); return newPasswordFieldsInPageDetails.length === 0; } @@ -175,7 +198,10 @@ export class InlineMenuFieldQualificationService // If the page does not contain any password fields, it might be part of a multistep login form. // That will only be the case if the field does not explicitly have its autocomplete attribute // set to "off" or "false". - return !this.autocompleteDisabledValues.has(field.autoCompleteType); + return !this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.autocompleteDisabledValues, + ); } // If the field is structured within a form, but no password fields are present in the form, @@ -183,7 +209,12 @@ export class InlineMenuFieldQualificationService if (passwordFieldsInPageDetails.length === 0) { // If the field's autocomplete is set to a disabled value, we should assume that the field is // not part of a login form. - if (this.autocompleteDisabledValues.has(field.autoCompleteType)) { + if ( + this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.autocompleteDisabledValues, + ) + ) { return false; } @@ -212,7 +243,10 @@ export class InlineMenuFieldQualificationService // If no visible password fields are found, this field might be part of a multipart form. // Check for an invalid autocompleteType to determine if the field is part of a login form. - return !this.autocompleteDisabledValues.has(field.autoCompleteType); + return !this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.autocompleteDisabledValues, + ); } /** @@ -237,7 +271,13 @@ export class InlineMenuFieldQualificationService * @param field - The field to validate */ private isCurrentPasswordField = (field: AutofillField): boolean => { - if (field.autoCompleteType === "new-password") { + if ( + this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.newPasswordAutoCompleteValues, + ) || + this.keywordsFoundInFieldData(field, [...this.accountCreationFieldKeywords]) + ) { return false; } @@ -250,11 +290,19 @@ export class InlineMenuFieldQualificationService * @param field - The field to validate */ private isNewPasswordField = (field: AutofillField): boolean => { - if (field.autoCompleteType === "current-password") { + if ( + this.fieldContainsAutocompleteValues( + field.autoCompleteType, + this.currentPasswordAutocompleteValues, + ) + ) { return false; } - return this.isPasswordField(field); + return ( + this.isPasswordField(field) && + this.keywordsFoundInFieldData(field, [...this.accountCreationFieldKeywords]) + ); }; /** @@ -422,6 +470,31 @@ export class InlineMenuFieldQualificationService return keywordValues; } + /** + * Separates the provided field data into space-separated values and checks if any + * of the values are present in the provided set of autocomplete values. + * + * @param fieldAutocompleteValue - The field autocomplete value to validate + * @param compareValues - The set of autocomplete values to check against + */ + private fieldContainsAutocompleteValues( + fieldAutocompleteValue: string, + compareValues: Set, + ) { + if (!fieldAutocompleteValue) { + return false; + } + + const autocompleteValueParts = fieldAutocompleteValue.split(" "); + for (let index = 0; index < autocompleteValueParts.length; index++) { + if (compareValues.has(autocompleteValueParts[index])) { + return true; + } + } + + return false; + } + /** * This method represents the previous rudimentary approach to qualifying fields for login forms. * From 3c7663a965fe050ef038d6dd34b91c4f15591731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Fri, 28 Jun 2024 21:58:15 +0200 Subject: [PATCH 037/130] [PM-7809] Fix memory leak in AngularThemingService for Safari extension (#9434) * [PM-7809] Fix memory leak in AngularThemingService for Safari * Use getSystemThemeFromWindow in createSystemThemeFromWindow --- .../src/popup/services/services.module.ts | 13 +++++++------ .../services/theming/angular-theming.service.ts | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index c7b5ca9b416..7c187d00514 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -1,6 +1,6 @@ import { APP_INITIALIZER, NgModule, NgZone } from "@angular/core"; import { Router } from "@angular/router"; -import { Subject, merge } from "rxjs"; +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"; @@ -485,14 +485,15 @@ const safeProviders: SafeProvider[] = [ provide: SYSTEM_THEME_OBSERVABLE, useFactory: (platformUtilsService: PlatformUtilsService) => { // Safari doesn't properly handle the (prefers-color-scheme) media query in the popup window, it always returns light. - // In Safari, we have to use the background page instead, which comes with limitations like not dynamically changing the extension theme when the system theme is changed. - let windowContext = window; + // This means we have to use the background page instead, which comes with limitations like not dynamically + // changing the extension theme when the system theme is changed. We also have issues with memory leaks when + // holding the reference to the background page. const backgroundWindow = BrowserApi.getBackgroundPage(); if (platformUtilsService.isSafari() && backgroundWindow) { - windowContext = backgroundWindow; + return of(AngularThemingService.getSystemThemeFromWindow(backgroundWindow)); + } else { + return AngularThemingService.createSystemThemeFromWindow(window); } - - return AngularThemingService.createSystemThemeFromWindow(windowContext); }, deps: [PlatformUtilsService], }), diff --git a/libs/angular/src/platform/services/theming/angular-theming.service.ts b/libs/angular/src/platform/services/theming/angular-theming.service.ts index d0f96eb4a7a..e8b78c90c46 100644 --- a/libs/angular/src/platform/services/theming/angular-theming.service.ts +++ b/libs/angular/src/platform/services/theming/angular-theming.service.ts @@ -18,11 +18,7 @@ export class AngularThemingService implements AbstractThemingService { static createSystemThemeFromWindow(window: Window): Observable { return merge( // This observable should always emit at least once, so go and get the current system theme designation - of( - window.matchMedia("(prefers-color-scheme: dark)").matches - ? ThemeType.Dark - : ThemeType.Light, - ), + of(AngularThemingService.getSystemThemeFromWindow(window)), // Start listening to changes fromEvent( window.matchMedia("(prefers-color-scheme: dark)"), @@ -31,6 +27,17 @@ export class AngularThemingService implements AbstractThemingService { ); } + /** + * Gets the currently active system theme based on the given window. + * @param window The window to query for the current theme. + * @returns The active system theme. + */ + static getSystemThemeFromWindow(window: Window): ThemeType { + return window.matchMedia("(prefers-color-scheme: dark)").matches + ? ThemeType.Dark + : ThemeType.Light; + } + readonly theme$ = this.themeStateService.selectedTheme$.pipe( switchMap((configuredTheme) => { if (configuredTheme === ThemeType.System) { From f0673dd16e1d5784c66b8fabae3121fb725ac028 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:30:05 -0400 Subject: [PATCH 038/130] PM-4950 - Fix hint and verify delete components that had the data in the wrong place (#9877) --- apps/web/src/app/oss-routing.module.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index dee6228530b..9e769fe0630 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -321,28 +321,28 @@ const routes: Routes = [ { path: "verify-recover-delete", canActivate: [unauthGuardFn()], + data: { + pageTitle: "deleteAccount", + titleId: "deleteAccount", + } satisfies DataProperties & AnonLayoutWrapperData, children: [ { path: "", component: VerifyRecoverDeleteComponent, - data: { - pageTitle: "deleteAccount", - titleId: "deleteAccount", - } satisfies DataProperties & AnonLayoutWrapperData, }, ], }, { path: "hint", canActivate: [unauthGuardFn()], + data: { + pageTitle: "passwordHint", + titleId: "passwordHint", + } satisfies DataProperties & AnonLayoutWrapperData, children: [ { path: "", component: HintComponent, - data: { - pageTitle: "passwordHint", - titleId: "passwordHint", - } satisfies DataProperties & AnonLayoutWrapperData, }, { path: "", From c23ee3b98aefac9d1cf593bfa75bb1b1c18d41c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Sun, 30 Jun 2024 00:48:56 +0200 Subject: [PATCH 039/130] 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> --- .../vault/popup/components/fido2/fido2.component.ts | 11 +++++++---- .../popup/components/vault/add-edit.component.ts | 8 ++++++++ .../fido2/fido2-authenticator.service.spec.ts | 2 +- .../services/fido2/fido2-authenticator.service.ts | 6 +++++- 4 files changed, 21 insertions(+), 6 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 049dc30ef61..752a9100721 100644 --- a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts +++ b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts @@ -256,7 +256,7 @@ export class Fido2Component implements OnInit, OnDestroy { const name = data.credentialName || data.rpId; // TODO: Revert to check for user verification once user verification for passkeys is approved for production. // PM-4577 - https://github.com/bitwarden/clients/pull/8746 - await this.createNewCipher(name); + await this.createNewCipher(name, data.userName); // We are bypassing user verification pending approval. this.send({ @@ -310,6 +310,7 @@ export class Fido2Component implements OnInit, OnDestroy { name: data.credentialName || data.rpId, uri: this.url, uilocation: "popout", + username: data.userName, senderTabId: this.senderTabId, sessionId: this.sessionId, userVerification: data.userVerification, @@ -357,11 +358,13 @@ export class Fido2Component implements OnInit, OnDestroy { this.destroy$.complete(); } - private buildCipher(name: string) { + private buildCipher(name: string, username: string) { this.cipher = new CipherView(); this.cipher.name = name; + this.cipher.type = CipherType.Login; this.cipher.login = new LoginView(); + this.cipher.login.username = username; this.cipher.login.uris = [new LoginUriView()]; this.cipher.login.uris[0].uri = this.url; this.cipher.card = new CardView(); @@ -371,8 +374,8 @@ export class Fido2Component implements OnInit, OnDestroy { this.cipher.reprompt = CipherRepromptType.None; } - private async createNewCipher(name: string) { - this.buildCipher(name); + private async createNewCipher(name: string, username: string) { + this.buildCipher(name, username); const cipher = await this.cipherService.encrypt(this.cipher); try { await this.cipherService.createWithServer(cipher); 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 bf7a6b07a5c..e72077fa82d 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 @@ -128,6 +128,14 @@ export class AddEditComponent extends BaseAddEditComponent { await this.load(); if (!this.editMode || this.cloneMode) { + // Only allow setting username if there's no existing value + if ( + params.username && + (this.cipher.login.username == null || this.cipher.login.username === "") + ) { + this.cipher.login.username = params.username; + } + if (params.name && (this.cipher.name == null || this.cipher.name === "")) { this.cipher.name = params.name; } diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts index a8690da9e2b..5da67f807b7 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts @@ -214,7 +214,7 @@ describe("FidoAuthenticatorService", () => { expect(userInterfaceSession.confirmNewCredential).toHaveBeenCalledWith({ credentialName: params.rpEntity.name, - userName: params.userEntity.displayName, + userName: params.userEntity.name, userVerification, rpId: params.rpEntity.id, } as NewCredentialParams); diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts index 6a22f03cf73..47d76897a3b 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts @@ -111,7 +111,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr let pubKeyDer: ArrayBuffer; const response = await userInterfaceSession.confirmNewCredential({ credentialName: params.rpEntity.name, - userName: params.userEntity.displayName, + userName: params.userEntity.name, userVerification: params.requireUserVerification, rpId: params.rpEntity.id, }); @@ -145,6 +145,10 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr fido2Credential = await createKeyView(params, keyPair.privateKey); cipher.login.fido2Credentials = [fido2Credential]; + // update username if username is missing + if (Utils.isNullOrEmpty(cipher.login.username)) { + cipher.login.username = fido2Credential.userName; + } const reencrypted = await this.cipherService.encrypt(cipher); await this.cipherService.updateWithServer(reencrypted); credentialId = fido2Credential.credentialId; From e12e817d2266d61c3a7b89076cf6133bdc1c56c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Sun, 30 Jun 2024 00:50:18 +0200 Subject: [PATCH 040/130] 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 --- .../fido2/fido2-cipher-row.component.html | 1 + .../fido2/fido2-cipher-row.component.ts | 21 ++++++++++++++++++- .../src/vault/models/view/login.view.ts | 5 +++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.html b/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.html index edf20d3e9c3..852fd4a0e81 100644 --- a/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.html +++ b/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.html @@ -28,6 +28,7 @@ + {{ getSubName(cipher) }} {{ cipher.subTitle }}
    diff --git a/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.ts b/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.ts index c07d2ef8860..25d623b1692 100644 --- a/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.ts +++ b/apps/browser/src/vault/popup/components/fido2/fido2-cipher-row.component.ts @@ -1,10 +1,11 @@ -import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from "@angular/core"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @Component({ selector: "app-fido2-cipher-row", templateUrl: "fido2-cipher-row.component.html", + changeDetection: ChangeDetectionStrategy.OnPush, }) export class Fido2CipherRowComponent { @Output() onSelected = new EventEmitter(); @@ -17,4 +18,22 @@ export class Fido2CipherRowComponent { protected selectCipher(c: CipherView) { this.onSelected.emit(c); } + + /** + * Returns a subname for the cipher. + * If this has a FIDO2 credential, and the cipher.name is different from the FIDO2 credential's rpId, return the rpId. + * @param c Cipher + * @returns + */ + protected getSubName(c: CipherView): string | null { + const fido2Credentials = c.login?.fido2Credentials; + + if (!fido2Credentials || fido2Credentials.length === 0) { + return null; + } + + const [fido2Credential] = fido2Credentials; + + return c.name !== fido2Credential.rpId ? fido2Credential.rpId : null; + } } diff --git a/libs/common/src/vault/models/view/login.view.ts b/libs/common/src/vault/models/view/login.view.ts index 53bbc220225..1236e047b69 100644 --- a/libs/common/src/vault/models/view/login.view.ts +++ b/libs/common/src/vault/models/view/login.view.ts @@ -40,6 +40,11 @@ export class LoginView extends ItemView { } get subTitle(): string { + // if there's a passkey available, use that as a fallback + if (Utils.isNullOrEmpty(this.username) && this.fido2Credentials?.length > 0) { + return this.fido2Credentials[0].userName; + } + return this.username; } From 8f66d60a7ef8fe47986a6bc3fe7a89a92b61cc52 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Mon, 1 Jul 2024 06:50:42 +1000 Subject: [PATCH 041/130] [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 --- .../common/new-base.people.component.ts | 277 +++--------------- .../common/people-table-data-source.ts | 133 +++++++++ .../members/members-routing.module.ts | 4 +- ....component.html => members.component.html} | 29 +- ...ople.component.ts => members.component.ts} | 136 +++++---- .../organizations/members/members.module.ts | 4 +- 6 files changed, 282 insertions(+), 301 deletions(-) create mode 100644 apps/web/src/app/admin-console/common/people-table-data-source.ts rename apps/web/src/app/admin-console/organizations/members/{people.component.html => members.component.html} (93%) rename apps/web/src/app/admin-console/organizations/members/{people.component.ts => members.component.ts} (88%) diff --git a/apps/web/src/app/admin-console/common/new-base.people.component.ts b/apps/web/src/app/admin-console/common/new-base.people.component.ts index 17f504c74aa..90c25e840c0 100644 --- a/apps/web/src/app/admin-console/common/new-base.people.component.ts +++ b/apps/web/src/app/admin-console/common/new-base.people.component.ts @@ -1,7 +1,7 @@ -import { Directive, ViewChild, ViewContainerRef } from "@angular/core"; +import { Directive } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormControl } from "@angular/forms"; -import { firstValueFrom, lastValueFrom, debounceTime } from "rxjs"; +import { firstValueFrom, lastValueFrom, debounceTime, combineLatest, BehaviorSubject } from "rxjs"; import { UserNamePipe } from "@bitwarden/angular/pipes/user-name.pipe"; import { ModalService } from "@bitwarden/angular/services/modal.service"; @@ -18,88 +18,47 @@ import { ListResponse } from "@bitwarden/common/models/response/list.response"; 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"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { DialogService, TableDataSource } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { OrganizationUserView } from "../organizations/core/views/organization-user.view"; import { UserConfirmComponent } from "../organizations/manage/user-confirm.component"; -type StatusType = OrganizationUserStatusType | ProviderUserStatusType; +import { PeopleTableDataSource, peopleFilter } from "./people-table-data-source"; -const MaxCheckedCount = 500; +export type StatusType = OrganizationUserStatusType | ProviderUserStatusType; +export type UserViewTypes = ProviderUserUserDetailsResponse | OrganizationUserView; /** * A refactored copy of BasePeopleComponent, using the component library table and other modern features. * This will replace BasePeopleComponent once all subclasses have been changed over to use this class. */ @Directive() -export abstract class NewBasePeopleComponent< - UserView extends ProviderUserUserDetailsResponse | OrganizationUserView, -> { - @ViewChild("confirmTemplate", { read: ViewContainerRef, static: true }) - confirmModalRef: ViewContainerRef; - - get allCount() { - return this.activeUsers != null ? this.activeUsers.length : 0; - } - - get invitedCount() { - return this.statusMap.has(this.userStatusType.Invited) - ? this.statusMap.get(this.userStatusType.Invited).length - : 0; - } - - get acceptedCount() { - return this.statusMap.has(this.userStatusType.Accepted) - ? this.statusMap.get(this.userStatusType.Accepted).length - : 0; - } - - get confirmedCount() { - return this.statusMap.has(this.userStatusType.Confirmed) - ? this.statusMap.get(this.userStatusType.Confirmed).length - : 0; - } - - get revokedCount() { - return this.statusMap.has(this.userStatusType.Revoked) - ? this.statusMap.get(this.userStatusType.Revoked).length - : 0; - } - +export abstract class NewBasePeopleComponent { /** * Shows a banner alerting the admin that users need to be confirmed. */ get showConfirmUsers(): boolean { return ( - this.activeUsers != null && - this.statusMap != null && - this.activeUsers.length > 1 && - this.confirmedCount > 0 && - this.confirmedCount < 3 && - this.acceptedCount > 0 + this.dataSource.activeUserCount > 1 && + this.dataSource.confirmedUserCount > 0 && + this.dataSource.confirmedUserCount < 3 && + this.dataSource.acceptedUserCount > 0 ); } get showBulkConfirmUsers(): boolean { - return this.acceptedCount > 0; + return this.dataSource.acceptedUserCount > 0; } abstract userType: typeof OrganizationUserType | typeof ProviderUserType; abstract userStatusType: typeof OrganizationUserStatusType | typeof ProviderUserStatusType; - protected dataSource = new TableDataSource(); + protected abstract dataSource: PeopleTableDataSource; firstLoaded: boolean; - /** - * A hashmap that groups users by their status (invited/accepted/etc). This is used by the toggles to show - * user counts and filter data by user status. - */ - statusMap = new Map(); - /** * The currently selected status filter, or null to show all active users. */ @@ -110,22 +69,12 @@ export abstract class NewBasePeopleComponent< */ actionPromise: Promise; - /** - * All users, loaded from the server, before any filtering has been applied. - */ - protected allUsers: UserView[] = []; - - /** - * Active users only, that is, users that are not in the revoked status. - */ - protected activeUsers: UserView[] = []; - protected searchControl = new FormControl("", { nonNullable: true }); + protected statusToggle = new BehaviorSubject(null); constructor( protected apiService: ApiService, protected i18nService: I18nService, - protected platformUtilsService: PlatformUtilsService, protected cryptoService: CryptoService, protected validationService: ValidationService, protected modalService: ModalService, @@ -133,18 +82,19 @@ export abstract class NewBasePeopleComponent< protected userNamePipe: UserNamePipe, protected dialogService: DialogService, protected organizationManagementPreferencesService: OrganizationManagementPreferencesService, + protected toastService: ToastService, ) { - // Connect the search input to the table dataSource filter input - this.searchControl.valueChanges - .pipe(debounceTime(200), takeUntilDestroyed()) - .subscribe((v) => (this.dataSource.filter = v)); + // Connect the search input and status toggles to the table dataSource filter + combineLatest([this.searchControl.valueChanges.pipe(debounceTime(200)), this.statusToggle]) + .pipe(takeUntilDestroyed()) + .subscribe( + ([searchText, status]) => (this.dataSource.filter = peopleFilter(searchText, status)), + ); } abstract edit(user: UserView): void; abstract getUsers(): Promise | UserView[]>; abstract deleteUser(id: string): Promise; - abstract revokeUser(id: string): Promise; - abstract restoreUser(id: string): Promise; abstract reinviteUser(id: string): Promise; abstract confirmUser(user: UserView, publicKey: Uint8Array): Promise; @@ -152,70 +102,16 @@ export abstract class NewBasePeopleComponent< // Load new users from the server const response = await this.getUsers(); - // Reset and repopulate the statusMap - this.statusMap.clear(); - this.activeUsers = []; - for (const status of Utils.iterateEnum(this.userStatusType)) { - this.statusMap.set(status, []); - } - + // GetUsers can return a ListResponse or an Array if (response instanceof ListResponse) { - this.allUsers = response.data != null && response.data.length > 0 ? response.data : []; + this.dataSource.data = response.data != null && response.data.length > 0 ? response.data : []; } else if (Array.isArray(response)) { - this.allUsers = response; + this.dataSource.data = response; } - this.allUsers.forEach((u) => { - if (!this.statusMap.has(u.status)) { - this.statusMap.set(u.status, [u]); - } else { - this.statusMap.get(u.status).push(u); - } - if (u.status !== this.userStatusType.Revoked) { - this.activeUsers.push(u); - } - }); - - // Filter based on UserStatus - this also populates the table on first load - this.filter(this.status); - this.firstLoaded = true; } - /** - * Filter the data source by user status. - * This overwrites dataSource.data because this filtering needs to apply first, before the search input - */ - filter(status: StatusType | null) { - this.status = status; - if (this.status != null) { - this.dataSource.data = this.statusMap.get(this.status); - } else { - this.dataSource.data = this.activeUsers; - } - // Reset checkbox selection - this.selectAll(false); - } - - checkUser(user: UserView, select?: boolean) { - (user as any).checked = select == null ? !(user as any).checked : select; - } - - selectAll(select: boolean) { - if (select) { - // Reset checkbox selection first so we know nothing else is selected - this.selectAll(false); - } - - const filteredUsers = this.dataSource.filteredData; - - const selectCount = - select && filteredUsers.length > MaxCheckedCount ? MaxCheckedCount : filteredUsers.length; - for (let i = 0; i < selectCount; i++) { - this.checkUser(filteredUsers[i], select); - } - } - invite() { this.edit(null); } @@ -237,59 +133,12 @@ export abstract class NewBasePeopleComponent< this.actionPromise = this.deleteUser(user.id); try { await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("removedUserId", this.userNamePipe.transform(user)), - ); - this.removeUser(user); - } catch (e) { - this.validationService.showError(e); - } - this.actionPromise = null; - } - - protected async revokeUserConfirmationDialog(user: UserView) { - return this.dialogService.openSimpleDialog({ - title: { key: "revokeAccess", placeholders: [this.userNamePipe.transform(user)] }, - content: this.revokeWarningMessage(), - acceptButtonText: { key: "revokeAccess" }, - type: "warning", - }); - } - - async revoke(user: UserView) { - const confirmed = await this.revokeUserConfirmationDialog(user); - - if (!confirmed) { - return false; - } - - this.actionPromise = this.revokeUser(user.id); - try { - await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("revokedUserId", this.userNamePipe.transform(user)), - ); - await this.load(); - } catch (e) { - this.validationService.showError(e); - } - this.actionPromise = null; - } - - async restore(user: UserView) { - this.actionPromise = this.restoreUser(user.id); - try { - await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("restoredUserId", this.userNamePipe.transform(user)), - ); - await this.load(); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("removedUserId", this.userNamePipe.transform(user)), + }); + this.dataSource.removeUser(user); } catch (e) { this.validationService.showError(e); } @@ -304,11 +153,11 @@ export abstract class NewBasePeopleComponent< this.actionPromise = this.reinviteUser(user.id); try { await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("hasBeenReinvited", this.userNamePipe.transform(user)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("hasBeenReinvited", this.userNamePipe.transform(user)), + }); } catch (e) { this.validationService.showError(e); } @@ -316,25 +165,18 @@ export abstract class NewBasePeopleComponent< } async confirm(user: UserView) { - function updateUser(self: NewBasePeopleComponent) { - user.status = self.userStatusType.Confirmed; - const mapIndex = self.statusMap.get(self.userStatusType.Accepted).indexOf(user); - if (mapIndex > -1) { - self.statusMap.get(self.userStatusType.Accepted).splice(mapIndex, 1); - self.statusMap.get(self.userStatusType.Confirmed).push(user); - } - } - const confirmUser = async (publicKey: Uint8Array) => { try { this.actionPromise = this.confirmUser(user, publicKey); await this.actionPromise; - updateUser(this); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("hasBeenConfirmed", this.userNamePipe.transform(user)), - ); + user.status = this.userStatusType.Confirmed; + this.dataSource.replaceUser(user); + + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("hasBeenConfirmed", this.userNamePipe.transform(user)), + }); } catch (e) { this.validationService.showError(e); throw e; @@ -379,37 +221,4 @@ export abstract class NewBasePeopleComponent< this.logService.error(`Handled exception: ${e}`); } } - - protected revokeWarningMessage(): string { - return this.i18nService.t("revokeUserConfirmation"); - } - - protected getCheckedUsers() { - return this.dataSource.data.filter((u) => (u as any).checked); - } - - /** - * Remove a user row from the table and all related data sources - */ - protected removeUser(user: UserView) { - let index = this.dataSource.data.indexOf(user); - if (index > -1) { - // Clone the array so that the setter for dataSource.data is triggered to update the table rendering - const updatedData = [...this.dataSource.data]; - updatedData.splice(index, 1); - this.dataSource.data = updatedData; - } - - index = this.allUsers.indexOf(user); - if (index > -1) { - this.allUsers.splice(index, 1); - } - - if (this.statusMap.has(user.status)) { - index = this.statusMap.get(user.status).indexOf(user); - if (index > -1) { - this.statusMap.get(user.status).splice(index, 1); - } - } - } } diff --git a/apps/web/src/app/admin-console/common/people-table-data-source.ts b/apps/web/src/app/admin-console/common/people-table-data-source.ts new file mode 100644 index 00000000000..db357b4dbcd --- /dev/null +++ b/apps/web/src/app/admin-console/common/people-table-data-source.ts @@ -0,0 +1,133 @@ +import { + OrganizationUserStatusType, + ProviderUserStatusType, +} from "@bitwarden/common/admin-console/enums"; +import { TableDataSource } from "@bitwarden/components"; + +import { StatusType, UserViewTypes } from "./new-base.people.component"; + +const MaxCheckedCount = 500; + +/** + * Returns true if the user matches the status, or where the status is `null`, if the user is active (not revoked). + */ +function statusFilter(user: UserViewTypes, status: StatusType) { + if (status == null) { + return user.status != OrganizationUserStatusType.Revoked; + } + + return user.status === status; +} + +/** + * Returns true if the string matches the user's id, name, or email. + * (The default string search includes all properties, which can return false positives for collection names etc.) + */ +function textFilter(user: UserViewTypes, text: string) { + const normalizedText = text?.toLowerCase(); + return ( + !normalizedText || // null/empty strings should be ignored, i.e. always return true + user.email.toLowerCase().includes(normalizedText) || + user.id.toLowerCase().includes(normalizedText) || + user.name?.toLowerCase().includes(normalizedText) + ); +} + +export function peopleFilter(searchText: string, status: StatusType) { + return (user: UserViewTypes) => statusFilter(user, status) && textFilter(user, searchText); +} + +/** + * An extended TableDataSource class for managing people (organization members and provider users). + * It includes a tally of different statuses, utility methods, and other common functionality. + */ +export abstract class PeopleTableDataSource extends TableDataSource { + protected abstract statusType: typeof OrganizationUserStatusType | typeof ProviderUserStatusType; + + /** + * The number of 'active' users, that is, all users who are not in a revoked status. + */ + activeUserCount: number; + + invitedUserCount: number; + acceptedUserCount: number; + confirmedUserCount: number; + revokedUserCount: number; + + override set data(data: T[]) { + super.data = data; + + this.activeUserCount = + this.data?.filter((u) => u.status !== this.statusType.Revoked).length ?? 0; + + this.invitedUserCount = + this.data?.filter((u) => u.status === this.statusType.Invited).length ?? 0; + this.acceptedUserCount = + this.data?.filter((u) => u.status === this.statusType.Accepted).length ?? 0; + this.confirmedUserCount = + this.data?.filter((u) => u.status === this.statusType.Confirmed).length ?? 0; + this.revokedUserCount = + this.data?.filter((u) => u.status === this.statusType.Revoked).length ?? 0; + } + + override get data() { + // If you override a setter, you must also override the getter + return super.data; + } + + /** + * Check or uncheck a user in the table + * @param select check the user (true), uncheck the user (false), or toggle the current state (null) + */ + checkUser(user: T, select?: boolean) { + (user as any).checked = select == null ? !(user as any).checked : select; + } + + getCheckedUsers() { + return this.data.filter((u) => (u as any).checked); + } + + /** + * Check all filtered users (i.e. those rows that are currently visible) + * @param select check the filtered users (true) or uncheck the filtered users (false) + */ + checkAllFilteredUsers(select: boolean) { + if (select) { + // Reset checkbox selection first so we know nothing else is selected + this.uncheckAllUsers(); + } + + const filteredUsers = this.filteredData; + + const selectCount = + filteredUsers.length > MaxCheckedCount ? MaxCheckedCount : filteredUsers.length; + for (let i = 0; i < selectCount; i++) { + this.checkUser(filteredUsers[i], select); + } + } + + uncheckAllUsers() { + this.data.forEach((u) => ((u as any).checked = false)); + } + + /** + * Remove a user from the data source. Use this to ensure the table is re-rendered after the change. + */ + removeUser(user: T) { + // Note: use immutable functions so that we trigger setters to update the table + this.data = this.data.filter((u) => u != user); + } + + /** + * Replace a user in the data source by matching on user.id. Use this to ensure the table is re-rendered after the change. + */ + replaceUser(user: T) { + const index = this.data.findIndex((u) => u.id === user.id); + if (index > -1) { + // Clone the array so that the setter for dataSource.data is triggered to update the table rendering + const updatedData = this.data.slice(); + updatedData[index] = user; + this.data = updatedData; + } + } +} diff --git a/apps/web/src/app/admin-console/organizations/members/members-routing.module.ts b/apps/web/src/app/admin-console/organizations/members/members-routing.module.ts index a1d010deef5..d722ad6c0f9 100644 --- a/apps/web/src/app/admin-console/organizations/members/members-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/members/members-routing.module.ts @@ -5,12 +5,12 @@ import { canAccessMembersTab } from "@bitwarden/common/admin-console/abstraction import { OrganizationPermissionsGuard } from "../guards/org-permissions.guard"; -import { PeopleComponent } from "./people.component"; +import { MembersComponent } from "./members.component"; const routes: Routes = [ { path: "", - component: PeopleComponent, + component: MembersComponent, canActivate: [OrganizationPermissionsGuard], data: { titleId: "members", diff --git a/apps/web/src/app/admin-console/organizations/members/people.component.html b/apps/web/src/app/admin-console/organizations/members/members.component.html similarity index 93% rename from apps/web/src/app/admin-console/organizations/members/people.component.html rename to apps/web/src/app/admin-console/organizations/members/members.component.html index 9123b39a375..99afe8099a6 100644 --- a/apps/web/src/app/admin-console/organizations/members/people.component.html +++ b/apps/web/src/app/admin-console/organizations/members/members.component.html @@ -14,26 +14,35 @@
    - {{ "all" | i18n }} {{ allCount }} + {{ "all" | i18n }} + {{ + allCount + }} {{ "invited" | i18n }} - {{ invitedCount }} + {{ + invitedCount + }} {{ "needsConfirmation" | i18n }} - {{ acceptedCount }} + {{ + acceptedUserCount + }} {{ "revoked" | i18n }} - {{ revokedCount }} + {{ + revokedCount + }}
    @@ -67,7 +76,7 @@ type="checkbox" bitCheckbox class="tw-mr-1" - (change)="selectAll($any($event.target).checked)" + (change)="dataSource.checkAllFilteredUsers($any($event.target).checked)" id="selectAll" />