From f85b7b314c6a482f92c69d6a2061e8624115b252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Tom=C3=A9?= <108268980+r-tome@users.noreply.github.com> Date: Fri, 14 Jun 2024 06:38:50 +0100 Subject: [PATCH 01/29] [AC-1658] Update list command to show only organizations where the user is a member (#9453) * Refactor list organizations command to use organizationService.memberOrganizations$ * Deprecate OrganizationService.getAll method and update CLI get command to use the organizations observable --- apps/cli/src/commands/get.command.ts | 2 +- apps/cli/src/commands/list.command.ts | 4 +++- .../organization/organization.service.abstraction.ts | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index 142f0576b50..a91df2a1caa 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -468,7 +468,7 @@ export class GetCommand extends DownloadCommand { if (Utils.isGuid(id)) { org = await this.organizationService.getFromState(id); } else if (id.trim() !== "") { - let orgs = await this.organizationService.getAll(); + let orgs = await firstValueFrom(this.organizationService.organizations$); orgs = CliUtils.searchOrganizations(orgs, id); if (orgs.length > 1) { return Response.multipleResults(orgs.map((c) => c.id)); diff --git a/apps/cli/src/commands/list.command.ts b/apps/cli/src/commands/list.command.ts index 63ec13a8c97..536c9e3b8c2 100644 --- a/apps/cli/src/commands/list.command.ts +++ b/apps/cli/src/commands/list.command.ts @@ -1,3 +1,5 @@ +import { firstValueFrom } from "rxjs"; + import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; @@ -239,7 +241,7 @@ export class ListCommand { } private async listOrganizations(options: Options) { - let organizations = await this.organizationService.getAll(); + let organizations = await firstValueFrom(this.organizationService.memberOrganizations$); if (options.search != null && options.search.trim() !== "") { organizations = CliUtils.searchOrganizations(organizations, options.search); diff --git a/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts b/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts index 0b0e03e3e15..218051b9e4b 100644 --- a/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts +++ b/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts @@ -117,6 +117,9 @@ export abstract class OrganizationService { hasOrganizations: () => Promise; get$: (id: string) => Observable; get: (id: string) => Promise; + /** + * @deprecated This method is only used in key connector and will be removed soon as part of https://bitwarden.atlassian.net/browse/AC-2252. + */ getAll: (userId?: string) => Promise; /** From 5523447c4396ab5dd5ad6945cf2e7d00786e0c49 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 08:06:44 +0000 Subject: [PATCH 02/29] Autosync the updated translations (#9640) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/af/messages.json | 6 ---- apps/desktop/src/locales/ar/messages.json | 6 ---- apps/desktop/src/locales/az/messages.json | 8 +---- apps/desktop/src/locales/be/messages.json | 6 ---- apps/desktop/src/locales/bg/messages.json | 6 ---- apps/desktop/src/locales/bn/messages.json | 6 ---- apps/desktop/src/locales/bs/messages.json | 6 ---- apps/desktop/src/locales/ca/messages.json | 6 ---- apps/desktop/src/locales/cs/messages.json | 6 ---- apps/desktop/src/locales/cy/messages.json | 6 ---- apps/desktop/src/locales/da/messages.json | 6 ---- apps/desktop/src/locales/de/messages.json | 6 ---- apps/desktop/src/locales/el/messages.json | 10 ++---- apps/desktop/src/locales/en_GB/messages.json | 6 ---- apps/desktop/src/locales/en_IN/messages.json | 6 ---- apps/desktop/src/locales/eo/messages.json | 6 ---- apps/desktop/src/locales/es/messages.json | 6 ---- apps/desktop/src/locales/et/messages.json | 6 ---- apps/desktop/src/locales/eu/messages.json | 6 ---- apps/desktop/src/locales/fa/messages.json | 6 ---- apps/desktop/src/locales/fi/messages.json | 32 ++++++++------------ apps/desktop/src/locales/fil/messages.json | 6 ---- apps/desktop/src/locales/fr/messages.json | 6 ---- apps/desktop/src/locales/gl/messages.json | 6 ---- apps/desktop/src/locales/he/messages.json | 6 ---- apps/desktop/src/locales/hi/messages.json | 6 ---- apps/desktop/src/locales/hr/messages.json | 6 ---- apps/desktop/src/locales/hu/messages.json | 6 ---- apps/desktop/src/locales/id/messages.json | 6 ---- apps/desktop/src/locales/it/messages.json | 6 ---- apps/desktop/src/locales/ja/messages.json | 6 ---- apps/desktop/src/locales/ka/messages.json | 6 ---- apps/desktop/src/locales/km/messages.json | 6 ---- apps/desktop/src/locales/kn/messages.json | 6 ---- apps/desktop/src/locales/ko/messages.json | 6 ---- apps/desktop/src/locales/lt/messages.json | 6 ---- apps/desktop/src/locales/lv/messages.json | 22 +++++--------- apps/desktop/src/locales/me/messages.json | 6 ---- apps/desktop/src/locales/ml/messages.json | 6 ---- apps/desktop/src/locales/mr/messages.json | 6 ---- apps/desktop/src/locales/my/messages.json | 6 ---- apps/desktop/src/locales/nb/messages.json | 6 ---- apps/desktop/src/locales/ne/messages.json | 6 ---- apps/desktop/src/locales/nl/messages.json | 6 ---- apps/desktop/src/locales/nn/messages.json | 6 ---- apps/desktop/src/locales/or/messages.json | 6 ---- apps/desktop/src/locales/pl/messages.json | 6 ---- apps/desktop/src/locales/pt_BR/messages.json | 6 ---- apps/desktop/src/locales/pt_PT/messages.json | 6 ---- apps/desktop/src/locales/ro/messages.json | 6 ---- apps/desktop/src/locales/ru/messages.json | 6 ---- apps/desktop/src/locales/si/messages.json | 6 ---- apps/desktop/src/locales/sk/messages.json | 6 ---- apps/desktop/src/locales/sl/messages.json | 6 ---- apps/desktop/src/locales/sr/messages.json | 6 ---- apps/desktop/src/locales/sv/messages.json | 6 ---- apps/desktop/src/locales/te/messages.json | 6 ---- apps/desktop/src/locales/th/messages.json | 6 ---- apps/desktop/src/locales/tr/messages.json | 6 ---- apps/desktop/src/locales/uk/messages.json | 6 ---- apps/desktop/src/locales/vi/messages.json | 6 ---- apps/desktop/src/locales/zh_CN/messages.json | 26 ++++++---------- apps/desktop/src/locales/zh_TW/messages.json | 6 ---- 63 files changed, 34 insertions(+), 412 deletions(-) diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index 1c835869d63..42970d49be2 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Weier aantekening" }, - "approveLoginRequests": { - "message": "Bevestig aantekenings versoeke" - }, "logInConfirmedForEmailOnDevice": { "message": "Aantekening gebevestig vir $EMAIL$ op $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Hierdie versoek is nie meer geldig nie." }, - "approveLoginRequestDesc": { - "message": "Gebruik hierdie toestel om aantekenings versoeke, van ander toetstelle, goed te keer." - }, "confirmLoginAtemptForMail": { "message": "Bevestig aantekenings poging vir $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index 4f71977603a..32b4b48f512 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "رفض تسجيل الدخول" }, - "approveLoginRequests": { - "message": "الموافقة على طلبات تسجيل الدخول" - }, "logInConfirmedForEmailOnDevice": { "message": "تم تأكيد تسجيل الدخول لـ $EMAIL$ في $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "هذا الطلب لم يعد صالحًا." }, - "approveLoginRequestDesc": { - "message": "استخدم هذا الجهاز للموافقة على طلبات تسجيل الدخول من الأجهزة الأخرى." - }, "confirmLoginAtemptForMail": { "message": "تأكيد محاولة تسجيل الدخول لـ $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index dc2c5b28f8a..052b3ac3a9b 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -995,7 +995,7 @@ "message": "Menyu çubuğuna kiçildiləndə belə Bitwarden ikonunu Yuvada göstər." }, "confirmTrayTitle": { - "message": "Bildiriş sahəsi nişanını ləğv et" + "message": "Gizlətmə sahəsini təsdiqlə" }, "confirmTrayDesc": { "message": "Bu ayarı söndürsəniz, bütün əlaqəli ayarlar da söndürüləcək." @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Girişi rədd et" }, - "approveLoginRequests": { - "message": "Giriş tələblərini təsdiqlə" - }, "logInConfirmedForEmailOnDevice": { "message": "$DEVICE$ cihazında $EMAIL$ üçün giriş təsdiqləndi", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Bu tələb artıq yararsızdır." }, - "approveLoginRequestDesc": { - "message": "Digər cihazlardan edilən giriş tələblərini təsdiqləmək üçün bu cihazı istifadə edin." - }, "confirmLoginAtemptForMail": { "message": "$EMAIL$ üçün giriş cəhdini təsdiqlə", "placeholders": { diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index 73bd046a82d..075318ad609 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Адхіліць уваход" }, - "approveLoginRequests": { - "message": "Ухваліць запыт уваходу" - }, "logInConfirmedForEmailOnDevice": { "message": "Уваход пацверджаны для $EMAIL$ на $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Гэты запыт больш не дзейнічае." }, - "approveLoginRequestDesc": { - "message": "Выкарыстоўваць гэту прыладу для ўхвалення запытаў на ўваход, якія зроблены з іншых прылад." - }, "confirmLoginAtemptForMail": { "message": "Пацвердзіць спробу ўваходу для $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index 425380fdcea..68e217d3d21 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Отказване на вписването" }, - "approveLoginRequests": { - "message": "Одобряване на заявки за вписване" - }, "logInConfirmedForEmailOnDevice": { "message": "Вписването за $EMAIL$ на $DEVICE$ е одобрено", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Тази заявка вече не е активна." }, - "approveLoginRequestDesc": { - "message": "Използвайте това устройство за одобряване на заявки за вписване направени от други устройства." - }, "confirmLoginAtemptForMail": { "message": "Потвърждаване на заявката за вписване за $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index 36a4dc85f20..fa0aa398ef1 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 491c9413f99..2d9e2ebba00 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index 2fcc36136bb..207c1e553f1 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Denega l'inici de sessió" }, - "approveLoginRequests": { - "message": "Aprova les sol·licituds d'inici de sessió" - }, "logInConfirmedForEmailOnDevice": { "message": "S'ha confirmat l'inici de sessió per a $EMAIL$ a $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Aquesta sol·licitud ja no és vàlida." }, - "approveLoginRequestDesc": { - "message": "Utilitzeu aquest dispositiu per aprovar les sol·licituds d'inici de sessió fetes des d'altres dispositius." - }, "confirmLoginAtemptForMail": { "message": "Confirmeu l'intent d'inici de sessió per a $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 7dc48c3bf11..f0990d9f9f8 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Zamítnout přihlášení" }, - "approveLoginRequests": { - "message": "Schválit žádosti o přihlášení" - }, "logInConfirmedForEmailOnDevice": { "message": "Přihlášení bylo potvrzeno z $EMAIL$ pro $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Tento požadavek již není platný." }, - "approveLoginRequestDesc": { - "message": "Použije toto zařízení pro schvalování žádostí o přihlášení z jiných zařízení." - }, "confirmLoginAtemptForMail": { "message": "Potvrďte pokus o přihlášení z $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index bec1804ae2a..e92ffae7151 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index 333bfcd1800..96ae76f858b 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Afvis login" }, - "approveLoginRequests": { - "message": "Godkend loginanmodninger" - }, "logInConfirmedForEmailOnDevice": { "message": "Login bekræftet for $EMAIL$ på $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Anmodningen er ikke længere gyldig." }, - "approveLoginRequestDesc": { - "message": "Brug denne enhed til at godkende loginanmodninger fra andre enheder." - }, "confirmLoginAtemptForMail": { "message": "Bekræft loginforsøg for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 769be2a4295..7b366036e94 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Anmeldung ablehnen" }, - "approveLoginRequests": { - "message": "Anmeldeanfragen genehmigen" - }, "logInConfirmedForEmailOnDevice": { "message": "Anmeldung von $EMAIL$ auf $DEVICE$ bestätigt", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Diese Anfrage ist nicht mehr gültig." }, - "approveLoginRequestDesc": { - "message": "Benutze dieses Gerät, um Anmeldeanfragen von anderen Geräten zu genehmigen." - }, "confirmLoginAtemptForMail": { "message": "Anmeldeversuch von $EMAIL$ genehmigen", "placeholders": { diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index fd261a8d032..21ddb65a9ef 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -696,10 +696,10 @@ "message": "Καθορίστε τη βασική διεύθυνση URL, της εγκατάστασης του Bitwarden που φιλοξενείται στο χώρο σας." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Καθορίστε τη βασική διεύθυνση URL της εγκατάστασης Bitwarden στον τομέα σας. Παράδειγμα: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "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." @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Άρνηση σύνδεσης" }, - "approveLoginRequests": { - "message": "Έγκριση αιτημάτων σύνδεσης" - }, "logInConfirmedForEmailOnDevice": { "message": "Επιβεβαιώθηκε η σύνδεση του $EMAIL$ στη συσκευή $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Αυτό το αίτημα δεν είναι πλέον έγκυρο." }, - "approveLoginRequestDesc": { - "message": "Χρησιμοποιήστε αυτήν τη συσκευή για να εγκρίνετε αιτήματα σύνδεσης από άλλες συσκευές." - }, "confirmLoginAtemptForMail": { "message": "Επιβεβαίωση προσπάθειας σύνδεσης για $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index 7f28fee4b2c..f15b661034f 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index b3e9a40bb38..1d4809c927b 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 4a429118976..146a1231072 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index a3a2caf2e5a..a5b352e1456 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Denegar inicio de sesión" }, - "approveLoginRequests": { - "message": "Aprobar solicitudes de inicio de sesión" - }, "logInConfirmedForEmailOnDevice": { "message": "Inicio de sesión confirmado para $EMAIL$ en $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Esta solicitud ya no es válida." }, - "approveLoginRequestDesc": { - "message": "Utilice este dispositivo para aprobar las peticiones de inicio de sesión realizadas desde otros dispositivos." - }, "confirmLoginAtemptForMail": { "message": "Confirmar intento de inicio de sesión para $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index a38790c47ab..c7d48fd3991 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Tühista sisselogimine" }, - "approveLoginRequests": { - "message": "Sisselogimise päringute kinnitamine" - }, "logInConfirmedForEmailOnDevice": { "message": "$EMAIL$ sisselogimine seadmes $DEVICE$ on kinnitatud", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "See päring ei ole enam kehtiv." }, - "approveLoginRequestDesc": { - "message": "Kasuta seda seadet, et kinnitada teistes seadmetes tehtavad sisselogimised." - }, "confirmLoginAtemptForMail": { "message": "Kinnita sisselogimise katse $EMAIL$-le", "placeholders": { diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index a3b0f0f87b2..89a63fbe913 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index 7fe2758ec40..6852f1e1ecb 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "رد ورود" }, - "approveLoginRequests": { - "message": "درخواست های ورود را تأیید کنید" - }, "logInConfirmedForEmailOnDevice": { "message": "ورود به سیستم برای $EMAIL$ در $DEVICE$ تأیید شد", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "این درخواست دیگر معتبر نیست." }, - "approveLoginRequestDesc": { - "message": "از این دستگاه برای تأیید درخواست‌های ورود به سیستم از دستگاه‌های دیگر استفاده کنید." - }, "confirmLoginAtemptForMail": { "message": "تأیید تلاش برای ورود به سیستم برای $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 4586511cab4..d83f6c7d4ef 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -696,13 +696,13 @@ "message": "Määritä omassa palvelinympäristössäsi suoritettavan Bitwarden-asennuksen pääverkkotunnus." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Määritä itse ylläpitämäsi Bitwarden-asennuksen perusosoite. Esimerkki: https://bitwarden.yritys.fi." }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Edistynyttä määritystä varten voit syöttää jokaisen palvelun perusosoitteen erikseen." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Sinun on lisättävä joko palvelimen perusosoite tai ainakin yksi mukautettu palvelinympäristö." }, "customEnvironment": { "message": "Mukautettu palvelinympäristö" @@ -753,7 +753,7 @@ "message": "Kirjauduttu ulos" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Sinut on kirjattu ulos tililtäsi." }, "loginExpired": { "message": "Kirjautumisistuntosi on erääntynyt." @@ -827,7 +827,7 @@ "description": "A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing." }, "goToWebVault": { - "message": "Siirry verkkoholviin" + "message": "Avaa verkkoholvi" }, "getMobileApp": { "message": "Hanki mobiilisovellus" @@ -1225,10 +1225,10 @@ } }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Käyttötunnisteen päivitysvirhe" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Päivitystunnistetta tai API-avaimia ei löytynyt. Kokeile kirjautua ulos ja takaisin sisään." }, "help": { "message": "Ohje" @@ -2224,7 +2224,7 @@ } }, "forwaderInvalidToken": { - "message": "Virheellinen $SERVICENAME$ -rajapinnan tunniste", + "message": "Virheellinen $SERVICENAME$ API -tunniste", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2234,7 +2234,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Virheellinen $SERVICENAME$ -rajapinnan tunniste: $ERRORMESSAGE$", + "message": "Virheellinen $SERVICENAME$ API -tunniste: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2248,7 +2248,7 @@ } }, "forwarderNoAccountId": { - "message": "$SERVICENAME$ -palvelun peittämän sähköpostitilin tunnistetta ei saatu.", + "message": "$SERVICENAME$ -palvelun peittämän sähköpostitilin tunnusta ei saatu.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Hylkää kirjautuminen" }, - "approveLoginRequests": { - "message": "Hyväksy kirjautumispyyntöjä" - }, "logInConfirmedForEmailOnDevice": { "message": "Kirjautuminen vahvistettu tunnuksella $EMAIL$ alustalla $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Pyyntö ei ole enää voimassa." }, - "approveLoginRequestDesc": { - "message": "Hyväksy muiden laitteiden kirjautumispyynnöt tältä laitteelta." - }, "confirmLoginAtemptForMail": { "message": "Vahvista kirjautuminen tunnuksella $EMAIL$", "placeholders": { @@ -2493,10 +2487,10 @@ "message": "Tärkeää:" }, "accessTokenUnableToBeDecrypted": { - "message": "You have been logged out because your access token could not be decrypted. Please log in again to resolve this issue." + "message": "Sinut on kirjattu ulos, koska käyttötunnisteesi salausta ei voitu purkaa. Ratkaise ongelma kirjautumalla sisään uudelleen." }, "refreshTokenSecureStorageRetrievalFailure": { - "message": "You have been logged out because your refresh token could not be retrieved. Please log in again to resolve this issue." + "message": "Sinut on kirjattu ulos, koska päivitystunnistettasi ei voitu noutaa. Ratkaise ongelma kirjautumalla sisään uudelleen." }, "masterPasswordHint": { "message": "Pääsalasanasi palauttaminen ei ole mahdollista, jos unohdat sen!" @@ -2584,7 +2578,7 @@ "message": "pakollinen" }, "search": { - "message": "Etsi" + "message": "Haku" }, "inputMinLength": { "message": "Syötteen tulee sisältää ainakin $COUNT$ merkkiä.", diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index d4b76de533d..fe1ef417712 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Tanggihan ang pag login" }, - "approveLoginRequests": { - "message": "Aprubahan ang mga kahilingan sa pag login" - }, "logInConfirmedForEmailOnDevice": { "message": "Nakumpirma ang pag-login para sa $EMAIL$ sa $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Hindi na valid ang request na ito." }, - "approveLoginRequestDesc": { - "message": "Gamitin ang device na ito para aprubahan ang mga kahilingan sa pag-login na ginawa mula sa iba pang mga device." - }, "confirmLoginAtemptForMail": { "message": "Kumpirmahin ang pagtatangka sa pag-login para sa $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index a4288526277..e971256036b 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Refuser la connexion" }, - "approveLoginRequests": { - "message": "Approuver les demandes de connexion" - }, "logInConfirmedForEmailOnDevice": { "message": "Connexion confirmée pour $EMAIL$ sur $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Cette demande n'est plus valide." }, - "approveLoginRequestDesc": { - "message": "Utiliser cet appareil pour approuver les demandes de connexion faites à partir d'autres appareils." - }, "confirmLoginAtemptForMail": { "message": "Confirmer la tentative de connexion pour $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index 4d0d96038f6..d9b67aee6f3 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index b559652ce3d..3f3ef43c467 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "ביטול התחברות" }, - "approveLoginRequests": { - "message": "אישור בקשות התחברות" - }, "logInConfirmedForEmailOnDevice": { "message": "התחברות אושרה עבור $EMAIL$ במכשיר $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index bc4bf462f6b..7bd57bf6919 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index 2adc28e3ced..190e32d91ee 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Odbij prijavu" }, - "approveLoginRequests": { - "message": "Odobri pokušaje prijave" - }, "logInConfirmedForEmailOnDevice": { "message": "Prijava za $EMAIL$ potvrđena na uređaju $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Ovaj zahtjev više nije valjan." }, - "approveLoginRequestDesc": { - "message": "Koristi ovaj uređaj za odobrenje zahtjeva za prijavu na drugim uređajima." - }, "confirmLoginAtemptForMail": { "message": "Potvrdi pokušaj prijave za $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 568dc954e92..78c7797ff11 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Bejelentkezés megtagadása" }, - "approveLoginRequests": { - "message": "Bejelentkezési kérelmek jóváhagyása" - }, "logInConfirmedForEmailOnDevice": { "message": "A bejelelentketés $EMAIL$ email címmel megerősítésre került $DEVICE$ eszközön.", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "A kérés a továbbiakban már nem érvényes." }, - "approveLoginRequestDesc": { - "message": "Ezen eszköz használata a más eszközökről történő bejelentkezési kérések jóváhagyására." - }, "confirmLoginAtemptForMail": { "message": "Bejelentkezési kísérlet megerősítése $EMAIL$ email címmel", "placeholders": { diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index 545901170fd..74f3fa79f4a 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index 72f2115460f..dfc1f92eaa4 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Nega accesso" }, - "approveLoginRequests": { - "message": "Approva richieste di accesso" - }, "logInConfirmedForEmailOnDevice": { "message": "Login per $EMAIL$ da $DEVICE$ confermato", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "La richiesta non è più valida." }, - "approveLoginRequestDesc": { - "message": "Usa questo dispositivo per approvare le richieste di accesso fatte da altri dispositivi." - }, "confirmLoginAtemptForMail": { "message": "Conferma il tentativo di accesso di $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 94e96a98b37..9d9b0b28f15 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "ログインを拒否" }, - "approveLoginRequests": { - "message": "ログインリクエストを承認する" - }, "logInConfirmedForEmailOnDevice": { "message": "$EMAIL$ に $DEVICE$ でのログインを承認しました", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "このリクエストは無効になりました。" }, - "approveLoginRequestDesc": { - "message": "このデバイスを使用して、他のデバイスからのログインリクエストを承認します。" - }, "confirmLoginAtemptForMail": { "message": "$EMAIL$ のログイン試行を確認", "placeholders": { diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 4d0d96038f6..d9b67aee6f3 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index 4d0d96038f6..d9b67aee6f3 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index 88e371b67fc..5b53742fb97 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 672e775af4e..d8686af9786 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "로그인 거부" }, - "approveLoginRequests": { - "message": "로그인 요청 승인" - }, "logInConfirmedForEmailOnDevice": { "message": "$DEVICE$에서 $EMAIL$(으)로의 로그인이 확인되었습니다", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "더 이상 유효하지 않은 요청입니다." }, - "approveLoginRequestDesc": { - "message": "다른 기기에서 발생하는 로그인 요청을 이 기기에서 승인할 수 있습니다." - }, "confirmLoginAtemptForMail": { "message": "$EMAIL$(으)로의 로그인 시도 확인", "placeholders": { diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index 68698617d47..726439fe48a 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Neleisti prisijungti" }, - "approveLoginRequests": { - "message": "Patvirtinti prisijungimo užklausas" - }, "logInConfirmedForEmailOnDevice": { "message": "$EMAIL$ prisijungimas patvirtinas $DEVICE$ įrenginyje", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Ši užklausa nebegalioja." }, - "approveLoginRequestDesc": { - "message": "Naudokite šį įrenginį, kad patvirtintumėte prisijungimo užklausas, pateiktas iš kitų įrenginių." - }, "confirmLoginAtemptForMail": { "message": "Patvirtinti bandymą prisijungti iš $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 4579c68742e..fa8d1a50bc8 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -696,13 +696,13 @@ "message": "Norādīt pašuzstādīta Bitwarden pamata URL." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Jānorāda sava pašizvietotā Bitward servera pamata URL. Piemērs: https://bitwarden.uznemums.lv" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Papildu konfigurācijā ir iespējams norādīt URL katram pakalpojumam atsevišķi." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Jāpievieno vai no servera pamata URL vai vismaz viena pielāgota vide." }, "customEnvironment": { "message": "Pielāgota vide" @@ -753,7 +753,7 @@ "message": "Atteicies" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Notika izrakstīšanās no Tava konta." }, "loginExpired": { "message": "Pieteikšanās sesija ir beigusies." @@ -1225,10 +1225,10 @@ } }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Piekļuves pilnvaras atsvaizināšanas kļūda" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Netika atrastas atsvaidzināšanas pilnvaras vai API atslēgas. Lūgums mēģināt izrakstīties un atkal pieteikties." }, "help": { "message": "Palīdzība" @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Atteikt pieteikšanos" }, - "approveLoginRequests": { - "message": "Apstiprināt pieteikšanās pieprasījumus" - }, "logInConfirmedForEmailOnDevice": { "message": "$EMAIL$ pieteikšanās apstiprināta ierīcē $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Šis pieprasījums vairs nav derīgs." }, - "approveLoginRequestDesc": { - "message": "Izmantot šo ierīci, lai apstiprinātu pieteikšanās pieprasījumus no citām ierīcēm." - }, "confirmLoginAtemptForMail": { "message": "Apstiprināt $EMAIL$ pieteikšanās mēģinājumu", "placeholders": { @@ -2493,10 +2487,10 @@ "message": "Svarīgi:" }, "accessTokenUnableToBeDecrypted": { - "message": "You have been logged out because your access token could not be decrypted. Please log in again to resolve this issue." + "message": "Notika izrakstīšanās, jo Tavu piekļuves pilnvaru nevarēja atšifrēt. Lūgums pieteikties atkārtoti, lai novērstu šo sarežģījumu." }, "refreshTokenSecureStorageRetrievalFailure": { - "message": "You have been logged out because your refresh token could not be retrieved. Please log in again to resolve this issue." + "message": "Notika izrakstīšanās, jo Tavu atsvaidzināšanas pilnvaru nevarēja iegūt. Lūgums pieteikties atkārtoti, lai novērstu šo sarežģījumu." }, "masterPasswordHint": { "message": "Galvenā parole nevar tikt atgūta, ja tā ir aizmirsta!" diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index dc8a3ebdeeb..42238a63eb4 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index 1316189317b..597c61a9bb3 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index 4d0d96038f6..d9b67aee6f3 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index 1ec3bb1630d..b3e3915c43f 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index 149d0f75773..d3880df4dbd 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Avslå innlogging" }, - "approveLoginRequests": { - "message": "Godkjenn innloggingsforespørsler" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Denne forespørselen er ikke lenger gyldig." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Bekreft påloggingsforsøket til $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index 3ad79ad8bf6..bf64ebd43c0 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index aafc348d908..25734ff4bf1 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Inloggen afwijzen" }, - "approveLoginRequests": { - "message": "Inlogverzoeken goedkeuren" - }, "logInConfirmedForEmailOnDevice": { "message": "Inloggen voor $EMAIL$ bevestigd op $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Dit verzoek is niet langer geldig." }, - "approveLoginRequestDesc": { - "message": "Gebruik dit apparaat voor het goedkeuren van inlogverzoeken van andere apparaten." - }, "confirmLoginAtemptForMail": { "message": "Inlogpoging voor $EMAIL$ bevestigen", "placeholders": { diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index e383a118310..23e3b5d69f5 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Godkjenn innloggingsførespurnadar" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index 8f2f11bc30f..f3d78c23588 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index 6acefb31b80..703e50c35f6 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Odrzuć logowanie" }, - "approveLoginRequests": { - "message": "Zatwierdź prośby logowania" - }, "logInConfirmedForEmailOnDevice": { "message": "Logowanie potwierdzone dla $EMAIL$ dnia $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Ta prośba nie jest już ważna." }, - "approveLoginRequestDesc": { - "message": "Użyj tego urządzenia, aby zatwierdzić prośby logowania z innych urządzeń." - }, "confirmLoginAtemptForMail": { "message": "Potwierdź próbę logowania dla $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index b9e051de18e..86789174228 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Negar acesso" }, - "approveLoginRequests": { - "message": "Aprovar solicitações de acesso" - }, "logInConfirmedForEmailOnDevice": { "message": "Acesso confirmado para $EMAIL$ em $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Este pedido não é mais válido." }, - "approveLoginRequestDesc": { - "message": "Use este dispositivo para aprovar solicitações de acesso feitas de outros dispositivos." - }, "confirmLoginAtemptForMail": { "message": "Confirmar tentativa de acesso de $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index a1fc775bdef..0360ad50432 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Recusar início de sessão" }, - "approveLoginRequests": { - "message": "Aprovar pedidos de início de sessão" - }, "logInConfirmedForEmailOnDevice": { "message": "Início de sessão confirmado para $EMAIL$ em $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Este pedido já não é válido." }, - "approveLoginRequestDesc": { - "message": "Utilize este dispositivo para aprovar pedidos de início de sessão efetuados a partir de outros dispositivos." - }, "confirmLoginAtemptForMail": { "message": "Confirmar tentativa de início de sessão de $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index 65800596c86..66182bfcbaf 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index 2392d902289..6aa413d9f11 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Запретить вход" }, - "approveLoginRequests": { - "message": "Одобрение запросов на вход" - }, "logInConfirmedForEmailOnDevice": { "message": "Вход подтвержден для $EMAIL$ на $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Этот запрос больше не действителен." }, - "approveLoginRequestDesc": { - "message": "Использовать это устройство для подтверждения запросов на вход, сделанных с других устройств." - }, "confirmLoginAtemptForMail": { "message": "Подтвердите попытку входа для $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index 1d518c4374d..14415f055f0 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index dc6aa65d84f..cbb20735337 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Odmietnuť prihlásenie" }, - "approveLoginRequests": { - "message": "Schvaľovanie žiadostí o prihlásenie" - }, "logInConfirmedForEmailOnDevice": { "message": "Potvrdené prihlásenie pomocou $EMAIL$ na $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Táto žiadosť už nie je platná." }, - "approveLoginRequestDesc": { - "message": "Použiť toto zariadenie na schvaľovanie požiadaviek na prihlásenie z iných zariadení." - }, "confirmLoginAtemptForMail": { "message": "Potvrdiť pokus o prihlásenie pomocou $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 86cb28289a9..361d484242e 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Odobri zahtevke za prijavo" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "S to napravo odobri zahtevke za prijavo, ki pridejo z drugih naprav." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 90b6e7292f0..76a8f63a321 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Одбиј пријављивање" }, - "approveLoginRequests": { - "message": "Одобравање захтева за пријављивање" - }, "logInConfirmedForEmailOnDevice": { "message": "Пријава потврђена за $EMAIL$ на $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Овај захтев више не важи." }, - "approveLoginRequestDesc": { - "message": "Користите овај уређај за одобравање захтева за пријављивање са других уређаја." - }, "confirmLoginAtemptForMail": { "message": "Потврдити пријаву за $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index 6d078a34e87..a821e5aedbf 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Neka inloggning" }, - "approveLoginRequests": { - "message": "Godkänn inloggningsförfrågningar" - }, "logInConfirmedForEmailOnDevice": { "message": "Inloggning bekräftad för $EMAIL$ på $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Denna begäran är inte längre giltig." }, - "approveLoginRequestDesc": { - "message": "Använd denna enhet för att godkänna inloggningsförfrågningar från andra enheter." - }, "confirmLoginAtemptForMail": { "message": "Bekräfta inloggningsförsök för $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index 4d0d96038f6..d9b67aee6f3 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index 827bbc8b867..b8541361afd 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 8d3d061a58e..8cd34296133 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Girişi reddet" }, - "approveLoginRequests": { - "message": "Giriş isteklerini onayla" - }, "logInConfirmedForEmailOnDevice": { "message": "$DEVICE$ cihazında $EMAIL$ girişi onaylandı", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Bu istek artık geçerli değil." }, - "approveLoginRequestDesc": { - "message": "Diğer cihazlardan yapılan giriş isteklerini onaylamak için bu cihazı kullan." - }, "confirmLoginAtemptForMail": { "message": "$EMAIL$ giriş isteğini onayla", "placeholders": { diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 0ac31300741..caffd391d09 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Заборонити вхід" }, - "approveLoginRequests": { - "message": "Схвалювати запити на вхід" - }, "logInConfirmedForEmailOnDevice": { "message": "Підтверджено вхід для $EMAIL$ на $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "Цей запит більше недійсний." }, - "approveLoginRequestDesc": { - "message": "Схвалювати запити на вхід, виконані з інших пристроїв." - }, "confirmLoginAtemptForMail": { "message": "Підтвердити спробу входу для $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index 70a920b8587..3b8fba2a400 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "Deny login" }, - "approveLoginRequests": { - "message": "Approve login requests" - }, "logInConfirmedForEmailOnDevice": { "message": "Login confirmed for $EMAIL$ on $DEVICE$", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "approveLoginRequestDesc": { - "message": "Use this device to approve login requests made from other devices." - }, "confirmLoginAtemptForMail": { "message": "Confirm login attempt for $EMAIL$", "placeholders": { diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 8a80875bbf3..47ce6b92262 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -696,13 +696,13 @@ "message": "指定您本地托管的 Bitwarden 安装的基础 URL。" }, "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 或至少添加一个自定义环境。" }, "customEnvironment": { "message": "自定义环境" @@ -753,7 +753,7 @@ "message": "已注销" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "您已注销您的账户。" }, "loginExpired": { "message": "您的登录会话已过期。" @@ -1225,10 +1225,10 @@ } }, "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 密钥。请尝试注销然后重新登录。" }, "help": { "message": "帮助" @@ -2248,7 +2248,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "无法获取 $SERVICENAME$ 电子邮件账户 ID。", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "拒绝登录" }, - "approveLoginRequests": { - "message": "批准登录请求" - }, "logInConfirmedForEmailOnDevice": { "message": "已确认 $EMAIL$ 在 $DEVICE$ 上的登录", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "此请求已失效。" }, - "approveLoginRequestDesc": { - "message": "使用此设备批准其他设备的登录请求。" - }, "confirmLoginAtemptForMail": { "message": "确认 $EMAIL$ 的登录尝试", "placeholders": { @@ -2493,10 +2487,10 @@ "message": "重要事项:" }, "accessTokenUnableToBeDecrypted": { - "message": "You have been logged out because your access token could not be decrypted. Please log in again to resolve this issue." + "message": "由于无法解密您的访问令牌,您已被注销。请重新登录以解决此问题。" }, "refreshTokenSecureStorageRetrievalFailure": { - "message": "You have been logged out because your refresh token could not be retrieved. Please log in again to resolve this issue." + "message": "由于无法获取您的访问令牌,您已被注销。请重新登录以解决此问题。" }, "masterPasswordHint": { "message": "主密码忘记后,将无法恢复!" @@ -2566,7 +2560,7 @@ "message": "批准后,您将收到通知。" }, "troubleLoggingIn": { - "message": "登录遇到问题?" + "message": "登录遇到问题吗?" }, "loginApproved": { "message": "登录已批准" diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index 47bcaae70e8..7c478d835f4 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -2401,9 +2401,6 @@ "denyLogIn": { "message": "拒絕登入" }, - "approveLoginRequests": { - "message": "批准登入要求" - }, "logInConfirmedForEmailOnDevice": { "message": "已確認 $EMAIL$ 在 $DEVICE$ 上的登入", "placeholders": { @@ -2438,9 +2435,6 @@ "thisRequestIsNoLongerValid": { "message": "此請求已失效" }, - "approveLoginRequestDesc": { - "message": "使用此裝置準予來自其他裝置的登入要求。" - }, "confirmLoginAtemptForMail": { "message": "確認 $EMAIL$ 的登入嘗試", "placeholders": { From fb4987b7b134468315eb8dfe8f087719b9999ed9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 08:21:47 +0000 Subject: [PATCH 03/29] Autosync the updated translations (#9642) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 40 +++----- apps/web/src/locales/ar/messages.json | 40 +++----- apps/web/src/locales/az/messages.json | 116 ++++++++++------------- apps/web/src/locales/be/messages.json | 40 +++----- apps/web/src/locales/bg/messages.json | 40 +++----- apps/web/src/locales/bn/messages.json | 40 +++----- apps/web/src/locales/bs/messages.json | 40 +++----- apps/web/src/locales/ca/messages.json | 40 +++----- apps/web/src/locales/cs/messages.json | 40 +++----- apps/web/src/locales/cy/messages.json | 40 +++----- apps/web/src/locales/da/messages.json | 40 +++----- apps/web/src/locales/de/messages.json | 40 +++----- apps/web/src/locales/el/messages.json | 40 +++----- apps/web/src/locales/en_GB/messages.json | 40 +++----- apps/web/src/locales/en_IN/messages.json | 40 +++----- apps/web/src/locales/eo/messages.json | 40 +++----- apps/web/src/locales/es/messages.json | 40 +++----- apps/web/src/locales/et/messages.json | 40 +++----- apps/web/src/locales/eu/messages.json | 40 +++----- apps/web/src/locales/fa/messages.json | 46 ++++----- apps/web/src/locales/fi/messages.json | 64 +++++-------- apps/web/src/locales/fil/messages.json | 40 +++----- apps/web/src/locales/fr/messages.json | 40 +++----- apps/web/src/locales/gl/messages.json | 40 +++----- apps/web/src/locales/he/messages.json | 40 +++----- apps/web/src/locales/hi/messages.json | 40 +++----- apps/web/src/locales/hr/messages.json | 40 +++----- apps/web/src/locales/hu/messages.json | 40 +++----- apps/web/src/locales/id/messages.json | 40 +++----- apps/web/src/locales/it/messages.json | 40 +++----- apps/web/src/locales/ja/messages.json | 40 +++----- apps/web/src/locales/ka/messages.json | 40 +++----- apps/web/src/locales/km/messages.json | 40 +++----- apps/web/src/locales/kn/messages.json | 40 +++----- apps/web/src/locales/ko/messages.json | 40 +++----- apps/web/src/locales/lv/messages.json | 74 ++++++--------- apps/web/src/locales/ml/messages.json | 40 +++----- apps/web/src/locales/mr/messages.json | 40 +++----- apps/web/src/locales/my/messages.json | 40 +++----- apps/web/src/locales/nb/messages.json | 40 +++----- apps/web/src/locales/ne/messages.json | 40 +++----- apps/web/src/locales/nl/messages.json | 40 +++----- apps/web/src/locales/nn/messages.json | 40 +++----- apps/web/src/locales/or/messages.json | 40 +++----- apps/web/src/locales/pl/messages.json | 40 +++----- apps/web/src/locales/pt_BR/messages.json | 40 +++----- apps/web/src/locales/pt_PT/messages.json | 40 +++----- apps/web/src/locales/ro/messages.json | 40 +++----- apps/web/src/locales/ru/messages.json | 40 +++----- apps/web/src/locales/si/messages.json | 40 +++----- apps/web/src/locales/sk/messages.json | 40 +++----- apps/web/src/locales/sl/messages.json | 40 +++----- apps/web/src/locales/sr/messages.json | 40 +++----- apps/web/src/locales/sr_CS/messages.json | 40 +++----- apps/web/src/locales/sv/messages.json | 40 +++----- apps/web/src/locales/te/messages.json | 40 +++----- apps/web/src/locales/th/messages.json | 40 +++----- apps/web/src/locales/tr/messages.json | 50 ++++------ apps/web/src/locales/uk/messages.json | 40 +++----- apps/web/src/locales/vi/messages.json | 40 +++----- apps/web/src/locales/zh_CN/messages.json | 58 +++++------- apps/web/src/locales/zh_TW/messages.json | 40 +++----- 62 files changed, 890 insertions(+), 1758 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 0fb5cf25f96..d33f9169660 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Teken aan" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Bestuurder" - }, - "managerDesc": { - "message": "Bestuurders bestuur en het toegang tot toegewysde versamelings in u organisasie." - }, "all": { "message": "Alle" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Toestemming" }, - "managerPermissions": { - "message": "Bestuurdertoestemmings" - }, - "adminPermissions": { - "message": "Admintoestemmings" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Skrap enige versameling" }, - "manageAssignedCollections": { - "message": "Bestuur toegekende versamelings" - }, "editAssignedCollections": { "message": "Wysig toegekende versamelings" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Verleen toegang tot alle huidige en toekomstige versamelings." - }, - "accessAllCollectionsHelp": { - "message": "Indien gemerk, vervang dit alle ander toestemmings op versamelings." - }, "selectMembers": { "message": "Kies lede" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Groep" }, - "groupAccessAll": { - "message": "Hierdie groep het toegang tot alle items en kan dit wysig." - }, - "memberAccessAll": { - "message": "Hierdie lid het toegang tot alle items en kan dit wysig." - }, "domainVerification": { "message": "Domeinverifikasie" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 6285e62d23f..0d083802d6f 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "تسجيل الدخول" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "بَدْء تسجيل الدخول" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "مدير" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index fb661923657..ac30934a405 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Giriş et" }, + "verifyIdentity": { + "message": "Kimliyinizi doğrulayın" + }, "logInInitiated": { "message": "Giriş etmə başladıldı" }, @@ -1069,13 +1072,13 @@ "message": "Sirlərin xaricə köçürülməsini təsdiqlə" }, "exportWarningDesc": { - "message": "Bu xaricə köçürmə, anbar verilənlərinizi şifrələnməmiş formatda ehtiva. Xaricə köçürülən faylı, güvənli olmayan kanallar üzərində saxlamamalı və ya göndərməməlisiniz (e-poçt kimi). Bu faylı işiniz bitdikdən sonra dərhal silin." + "message": "Bu xaricə köçürmə, anbar datanızı şifrələnməmiş formatda ehtiva edir. Xaricə köçürülən faylı, güvənli olmayan kanallar üzərində saxlamamalı və ya göndərməməlisiniz (e-poçt kimi). Bu faylı işiniz bitdikdən sonra dərhal silin." }, "exportSecretsWarningDesc": { "message": "Xaricə köçürdüyünüz bu fayldakı sirr datalarınız şifrələnməmiş formatdadır. Bu faylı güvənli olmayan kanallar (e-poçt kimi) üzərində saxlamamalı və ya göndərməməlisiniz. İşiniz bitdikdən sonra faylı dərhal silin." }, "encExportKeyWarningDesc": { - "message": "Bu ixrac faylı, hesabınızın şifrələmə açarını istifadə edərək verilənlərinizi şifrələyir. Hesabınızın şifrələmə açarını döndərsəniz, bu ixrac faylının şifrəsini aça bilməyəcəyiniz üçün yenidən ixrac etməli olacaqsınız." + "message": "Xaricə köçürdüyünüz bu fayldakı data, hesabınızın şifrələmə açarı istifadə edilərək şifrələnir. Hesabınızın şifrələmə açarını dəyişdirsəniz, bu faylın şifrəsini aça bilməyəcəksiniz və onu yenidən xaricə köçürməli olacaqsınız." }, "encExportAccountWarningDesc": { "message": "Hesab şifrələmə açarları, hər Bitwarden istifadəçi hesabı üçün unikaldır, buna görə də şifrələnmiş bir ixracı, fərqli bir hesaba idxal edə bilməzsiniz." @@ -1138,7 +1141,7 @@ "message": "Bu fayl parolla qorunur. Məlumatları daxilə köçürmək üçün fayl parolunu daxil edin." }, "exportSuccess": { - "message": "Anbar verilənləriniz ixrac edildi." + "message": "Anbar datası xaricə köçürüldü" }, "passwordGenerator": { "message": "Parol yaradıcı" @@ -1342,7 +1345,7 @@ "message": "Hesabı sil" }, "deleteAccountDesc": { - "message": "Hesabınızı və əlaqəli bütün verilənləri silmək üçün aşağıda davam edin." + "message": "Hesabınızı və bütün anbar datanızı silmək üçün aşağıdakı addımları izləyin." }, "deleteAccountWarning": { "message": "Hesabınızı silmək birdəfəlik prosesdir. Bu əməliyyatın geri dönüşü yoxdur." @@ -1351,7 +1354,7 @@ "message": "Hesab silindi" }, "accountDeletedDesc": { - "message": "Hesabınız bağlandı və bütün əlaqəli verilənlər silindi." + "message": "Hesabınız bağlandı və bütün əlaqələndirilmiş datalar silindi." }, "deleteOrganizationWarning": { "message": "Təşkilatınızı silmək birdəfəlik prosesdir. Bu əməliyyatın geri dönüşü yoxdur." @@ -1363,7 +1366,7 @@ "message": "Alətlər" }, "importData": { - "message": "Verilənləri idxal et" + "message": "Datanı daxilə köçür" }, "onboardingImportDataDetailsPartOne": { "message": "Daxilə köçürüləcək datanız yoxdursa, əvəzində yeni element yarada bilərsiniz.", @@ -1388,7 +1391,7 @@ "message": "Daxilə köçürməyə çalışdığınız data ilə bağlı bir problem var. Lütfən mənbə faylınızda aşağıda sadalanan xətaları həll edib yenidən sınayın." }, "importSuccess": { - "message": "Verilənlər anbarınıza uğurla idxal edildi." + "message": "Data uğurla daxilə köçürüldü" }, "importSuccessNumberOfItems": { "message": "Cəmi $AMOUNT$ element daxilə köçürüldü.", @@ -1403,7 +1406,7 @@ "message": "Məlumat uğurla xaricə köçürüldü" }, "importWarning": { - "message": "$ORGANIZATION$ təşkilatına verilənləri idxal edirsiniz. Verilənlərinizi bu təşkilatın üzvləri ilə paylaşa bilərsiniz. Davam etmək istəyirsiniz?", + "message": "Datanı $ORGANIZATION$ təşkilatına köçürürsünüz. Datanızı bu təşkilatın üzvləri ilə paylaşa bilərsiniz. Davam etmək istəyirsiniz?", "placeholders": { "organization": { "content": "$1", @@ -2006,7 +2009,7 @@ "message": "Pozulan hesablar tapıldı" }, "compromisedData": { - "message": "Ələ keçirilmiş verilənlər" + "message": "Ələ keçirilmiş data" }, "website": { "message": "Veb sayt" @@ -2077,7 +2080,7 @@ "message": "Fövqəladə hal müraciəti" }, "premiumSignUpReports": { - "message": "Anbarınızın təhlükəsiyini təmin etmək üçün parol gigiyenası, hesab sağlamlığı və verilənlərin pozulması hesabatları." + "message": "Anbarınızın güvənliyini təmin etmək üçün parol gigiyenası, hesab sağlamlığı və data pozuntusu hesabatları." }, "premiumSignUpTotp": { "message": "Anbarınızdakı hesablar üçün TOTP doğrulama kodu (2FA) yaradıcısı." @@ -2681,10 +2684,10 @@ "message": "Bu istifadəçini çıxartmaq istədiyinizə əminsiniz?" }, "removeOrgUserConfirmation": { - "message": "Bir üzv silinəndə, artıq onun təşkilat verilənlərinə müraciəti olmur və bu əməliyyatın geri dönüşü yoxdur. Üzvü təşkilata yenidən əlavə etmək üçün, onların dəvət edilib təkrar qoşulmaları lazımdır." + "message": "Bir üzv silindikdə, artıq həmin üzv təşkilat datasına müraciət edə bilmir və bu əməliyyatın geri dönüşü yoxdur. Həmin üzvü təşkilata yenidən əlavə etmək üçün, onu dəvət edib üzv olmasını təmin etmək lazımdır." }, "revokeUserConfirmation": { - "message": "Bir üzv ləğv ediləndə, artıq onun təşkilat verilənlərinə müraciəti olmur. Üzv müraciətini daha tez bərpa etmək üçün, Ləğv edilənlər vərəqinə gedin." + "message": "Bir üzv ləğv edildikdə, artıq həmin üzv təşkilat datasına müraciət edə bilmir. Üzv müraciətini daha tez bərpa etmək üçün, Ləğv edilənlər vərəqinə gedin." }, "removeUserConfirmationKeyConnector": { "message": "Xəbərdarlıq! Bu istifadəçi, şifrələmələrini idarə etmək üçün Açar Bağlayıcı tələb edir. Bu istifadəçini təşkilatınızdan silsəniz, hesabı birdəfəlik sıradan çıxarılacaq. Bu əməliyyatın geri dönüşü yoxdur. Davam etmək istəyirsiniz?" @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Təşkilatınızda təyin edilmiş kolleksiyalara müraciəti olan müntəzəm bir istifadəçi." }, - "manager": { - "message": "İdarəçi" - }, - "managerDesc": { - "message": "Təşkilatınızda təyin edilən kolleksiyalara müraciət edə və ya onları idarə edə bilər." - }, "all": { "message": "Hamısı" }, @@ -3461,7 +3458,7 @@ "message": "Təşkilat silindi" }, "organizationDeletedDesc": { - "message": "Təşkilat və əlaqəli bütün verilənləri silindi." + "message": "Təşkilat və əlaqələndirilmiş bütün datalar silindi." }, "organizationUpdated": { "message": "Təşkilat saxlanıldı" @@ -4344,34 +4341,34 @@ "message": "Fövqəladə hal müraciəti" }, "emergencyAccessDesc": { - "message": "Güvəndiyiniz əlaqələr fövqəladə hal müraciəti verin və ya idarə edin. Güvəndiyiniz əlaqələr, fövqəladə halda hesabınızı Görmək və ya Təhvil almaq üçün müraciət tələb edə bilər. Sıfır məlumat paylaşımının necə işlədiyi ilə bağlı daha ətraflı və detallı məlumat üçün kömək səhifəmizi ziyarət edin." + "message": "Güvənilən kontaktlara fövqəladə hal müraciəti verin və ya icazələri idarə edin. Güvənilən kontaktlar, fövqəladə halda hesabınızı Görmək və ya Təhvil almaq üçün müraciət tələb edə bilər. Sıfır məlumat paylaşımının necə işlədiyi ilə bağlı daha ətraflı və detallı məlumat üçün kömək səhifəmizi ziyarət edin." }, "emergencyAccessOwnerWarning": { "message": "Bir və ya daha çox təşkilata sahiblik edirsiniz. Fövqəladə hal üçün təyin olunmuş şəxsə təhvil alma müraciəti versəniz, təhvil aldıqdan sonra sahib olduğunuz bütün hüquqları istifadə edə bilər." }, "trustedEmergencyContacts": { - "message": "Güvənli fövqəladə hal əlaqələri" + "message": "Güvənilən fövqəladə hal kontaktları" }, "noTrustedContacts": { - "message": "Hələ ki, heç bir fövqəladə hal əlaqəsi əlavə etmədiniz, başlamaq üçün güvəndiyiniz bir əlaqəni dəvət edin." + "message": "Hələ ki, heç bir fövqəladə hal kontaktı əlavə etməmisiniz, başlamaq üçün güvəndiyiniz birini dəvət edin." }, "addEmergencyContact": { - "message": "Fövqəladə hal əlaqəsi əlavə et" + "message": "Fövqəladə hal kontaktı əlavə et" }, "designatedEmergencyContacts": { - "message": "Fövqəladə hal əlaqəsi kimi təyin edildi" + "message": "Fövqəladə hal kontaktı kimi təyin edilənlər" }, "noGrantedAccess": { - "message": "Hələ ki, heç kimi fövqəladə hal əlaqəsi kimi təyin etməmisiniz." + "message": "Hələ ki, heç kimi fövqəladə hal kontaktı kimi təyin etməmisiniz." }, "inviteEmergencyContact": { - "message": "Fövqəladə hal əlaqəsi üçün dəvət" + "message": "Fövqəladə hal kontaktını dəvət et" }, "editEmergencyContact": { - "message": "Fövqəladə hal əlaqəsinə düzəliş et" + "message": "Fövqəladə hal kontaktına düzəliş et" }, "inviteEmergencyContactDesc": { - "message": "Aşağıda Bitwarden hesabının e-poçt ünvanını daxil edərək yeni bir fövqəladə hal əlaqəsini dəvət edə bilərsiniz. Əgər Bitwarden hesabı yoxdursa, yeni bir hesab yaratmaları üçün istək göndəriləcək." + "message": "Aşağıda Bitwarden hesabının e-poçt ünvanını daxil edərək yeni bir fövqəladə hal kontaktını dəvət edə bilərsiniz. Əgər Bitwarden hesabı yoxdursa, yeni bir hesab yaratmaları üçün istək göndəriləcək." }, "emergencyAccessRecoveryInitiated": { "message": "Fövqəladə hal müraciəti başladıldı" @@ -4576,12 +4573,6 @@ "permission": { "message": "İcazə" }, - "managerPermissions": { - "message": "Menecer icazələri" - }, - "adminPermissions": { - "message": "Admin icazələri" - }, "accessEventLogs": { "message": "Tədbir jurnalına müraciət" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "İstənilən kolleksiyanı sil" }, - "manageAssignedCollections": { - "message": "Təyin edilmiş kolleksiyaları idarə et" - }, "editAssignedCollections": { "message": "Təyin edilmiş kolleksiyalara düzəliş et" }, @@ -4898,10 +4886,10 @@ "message": "Aşağıdakı istifadəçiləri çıxartmaq istədiyinizə əminsiniz? Bu prosesin tamamlanması bir neçə saniyə çəkir, ləğv edilə və ya dayandırıla bilməz." }, "removeOrgUsersConfirmation": { - "message": "Üzv(lər) silinəndə, artıq onun/onların təşkilat verilənlərinə müraciəti olmur və bu əməliyyatın geri dönüşü yoxdur. Üzvü təşkilata yenidən əlavə etmək üçün, onların dəvət edilib təkrar qoşulmaları lazımdır. Prosesin tamamlanması bir neçə saniyə çəkə bilər, bu proses dayandırıla və ya ləğv edilə bilməz." + "message": "Üzv(lər) silindikdə, artıq həmin üzv(lər) təşkilat datasına müraciət edə bilmir və bu əməliyyatın geri dönüşü yoxdur. Üzvü təşkilata yenidən əlavə etmək üçün, onu dəvət edib üzv olmasını təmin etmək lazımdır. Prosesin tamamlanması bir neçə saniyə çəkə bilər, bu proses dayandırıla və ya ləğv edilə bilməz." }, "revokeUsersWarning": { - "message": "Üzv(lər) ləğv ediləndə, artıq onun/onların təşkilat verilənlərinə müraciəti olmur. Üzv müraciətini daha tez bərpa etmək üçün, Ləğv edilənlər vərəqinə gedin. Prosesin tamamlanması bir neçə saniyə çəkə bilər, bu proses dayandırıla və ya ləğv edilə bilməz." + "message": "Üzv(lər) ləğv edildikə, artıq həmin üzv(lər) təşkilat datasına müraciət edə bilmir. Üzv müraciətini daha tez bərpa etmək üçün, Ləğv edilənlər vərəqinə gedin. Prosesin tamamlanması bir neçə saniyə çəkə bilər, bu proses dayandırıla və ya ləğv edilə bilməz." }, "theme": { "message": "Tema" @@ -5227,7 +5215,7 @@ "message": "Müştəri sirri" }, "metadataAddress": { - "message": "Meta verilənlər ünvanı" + "message": "Metadata ünvanı" }, "oidcRedirectBehavior": { "message": "OIDC yönləndirmə davranışı" @@ -5257,7 +5245,7 @@ "message": "SP Varlıq Kimliyi" }, "spMetadataUrl": { - "message": "SAML 2.0 Meta verilənlər URL-si" + "message": "SAML 2.0 metadata URL-si" }, "spAcsUrl": { "message": "İddia İstehlakçı Xidməti (ACS) URL-si" @@ -5320,10 +5308,10 @@ "message": "Ödənişsiz Bitwarden Ailələri" }, "sponsoredFamiliesEligible": { - "message": "Siz və ailəniz Ödənişsiz Bitwarden Ailələri üçün uyğunsunuz. İşdə olmadığınız vaxtlarda belə verilənlərinizi güvənli saxlamaq üçün özəl e-poçtunuzu istifadə edin." + "message": "Siz və ailəniz Ödənişsiz Bitwarden Ailələri üçün uyğunsunuz. İşdə olmadığınız vaxtlarda belə datanızı güvənli saxlamaq üçün özəl e-poçtunuzu istifadə edin." }, "sponsoredFamiliesEligibleCard": { - "message": "İşdə olmadığınız vaxtlarda belə verilənlərinizi güvənli saxlamaq üçün Ailələr üçün nəzərdə tutulan Ödənişsiz Bitwarden planını bu gün istifadə edin." + "message": "İşdə olmadığınız vaxtlarda belə datanızı güvənli saxlamaq üçün Ailələr üçün nəzərdə tutulan Ödənişsiz Bitwarden planını bu gün istifadə edin." }, "sponsoredFamiliesInclude": { "message": "Ailələr üçün Bitwarden planı bunları ehtiva edir" @@ -5458,7 +5446,7 @@ "message": "Yararsız doğrulama kodu" }, "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", @@ -5503,7 +5491,7 @@ "message": "Açar Bağlayıcı" }, "memberDecryptionKeyConnectorDescStart": { - "message": "SSO ilə Giriş etməni, öz-özünə sahiblik edən şifrə açma açar serverinizə bağlayın. Bu seçimi istifadə edərək, üzvlərin anbar verilənlərinin şifrəsini açmaq üçün Ana Parollarını istifadə etməsinə ehtiyac qalmayacaq.", + "message": "SSO ilə Girişi, self-hosted şifrə açma açar serverinizə bağlayın. Bu seçimi istifadə edərək, üzvlərin anbar datasının şifrəsini açmaq üçün Ana Parollarını istifadə etməsinə ehtiyac qalmayacaq.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Connect login with SSO to your self-hosted decryption key server. Using this option, members won’t need to use their master passwords to decrypt vault data. The require SSO authentication and single organization policies are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.'" }, "memberDecryptionKeyConnectorDescLink": { @@ -5572,7 +5560,7 @@ "message": "Faktura sinxr tokenini yarat" }, "copyPasteBillingSync": { - "message": "Bu tokeni kopyalayın və öz-özünə sahiblik edən təşkilatınızın Faktura sinxr ayarlarında yapışdırın." + "message": "Bu tokeni kopyalayın və self-hosted təşkilatınızın faktura sinxronlaşdırma ayarlarında yapışdırın." }, "billingSyncCanAccess": { "message": "Faktura sinxr tokeniniz, bu təşkilatın abunəlik ayarlarına müraciət edə və düzəliş edə bilər." @@ -5590,13 +5578,13 @@ "message": "Tokeni döndər" }, "rotateBillingSyncTokenWarning": { - "message": "Davam etsəniz, öz-özünə sahiblik edən serverinizdəki faktura sinxr təkrar quraşdırmalı olacaqsınız." + "message": "Davam etsəniz, self-hosted serverinizdəki faktura sinxronlaşdırmanı təkrar qurmalı olacaqsınız." }, "rotateBillingSyncTokenTitle": { "message": "Faktura sinxr tokenini döndərmək, əvvəlki tokeni yararsız edəcək." }, "selfHostedServer": { - "message": "öz-özünə sahiblik edən" + "message": "self-hosted" }, "customEnvironment": { "message": "Özəl mühit" @@ -5629,10 +5617,10 @@ "message": "Mühit URL-ləri saxlanıldı" }, "selfHostingTitle": { - "message": "Öz-özünə sahiblik etmə" + "message": "Self-hosting" }, "selfHostingEnterpriseOrganizationSectionCopy": { - "message": "Təşkilatınızı öz serverinizdə quraşdırmaq üçün lisenziya faylınızı yükləməlisiniz. Öz-özünə sahiblik edən təşkilatınız üçün ödənişsiz ailələr planlarını və qabaqcıl faktura özəlliklərini dəstəkləmək üçün, faktura sinxr quraşdırmalısınız." + "message": "Təşkilatınızı öz serverinizdə quraşdırmaq üçün lisenziya faylınızı yükləməlisiniz. Self-hosted təşkilatınız üçün Ödənişsiz Ailələr planlarını və qabaqcıl faktura özəlliklərini dəstəkləmək üçün, faktura sinxronlaşdırmanı qurmalısınız." }, "billingSyncApiKeyRotated": { "message": "Token döndərildi." @@ -5843,7 +5831,7 @@ } }, "awaitingSyncSingular": { - "message": "Token $DAYS$ gün əvvəl döndərildi. Öz-özünə sahiblik edən təşkilat ayarlarınızda faktura sinxr tokenini güncəlləyin.", + "message": "Token $DAYS$ gün əvvəl döndərildi. Self-hosted təşkilat ayarlarınızda faktura sinxronlaşdırma tokenini güncəlləyin.", "placeholders": { "days": { "content": "$1", @@ -5852,7 +5840,7 @@ } }, "awaitingSyncPlural": { - "message": "Token $DAYS$ gün əvvəl döndərildi. Öz-özünə sahiblik edən təşkilat ayarlarınızda faktura sinxr tokenini güncəlləyin.", + "message": "Token $DAYS$ gün əvvəl döndərildi. Self-hosted təşkilat ayarlarınızda faktura sinxronlaşdırma tokenini güncəlləyin.", "placeholders": { "days": { "content": "$1", @@ -5865,7 +5853,7 @@ "description": "Used as a prefix to indicate the last time a sync occured. Example \"Last sync 1968-11-16 00:00:00\"" }, "sponsorshipsSynced": { - "message": "Öz-özünə sahiblik edən sponsorluq sinxronlaşdırıldı." + "message": "Self-hosted sponsorluq sinxronlaşdırıldı." }, "billingManagedByProvider": { "message": "$PROVIDER$ tərəfindən idarə olunur", @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Yalnız idarə etdiyiniz kolleksiyaları təyin edə bilərsiniz." }, - "accessAllCollectionsDesc": { - "message": "Hazırkı və gələcəkdəki bütün kolleksiyalara müraciət icazəsi verin." - }, - "accessAllCollectionsHelp": { - "message": "İşarələnsə bu, digər bütün kolleksiya icazələrini əvəz edəcək." - }, "selectMembers": { "message": "Üzv seç" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Qrup" }, - "groupAccessAll": { - "message": "Bu qrup, bütün elementlərə müraciət edə və onları dəyişdirə bilər." - }, - "memberAccessAll": { - "message": "Bu üzv, bütün elementlərə müraciət edə və onları dəyişdirə bilər." - }, "domainVerification": { "message": "Domen doğrulaması" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Doğrulandı" + }, + "viewSecret": { + "message": "Sirrə bax" + }, + "noClients": { + "message": "Sadalanacaq heç bir client yoxdur" + }, + "providerBillingEmailHint": { + "message": "Bu e-poçt ünvanı, bu provayderə aid bütün fakturaları alacaq", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index 6cd2e5c77ea..42c4c496499 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Увайсці" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Ініцыяваны ўваход" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Звычайныя карыстальнікі з доступам да прызначаных калекцый у вашай арганізацыі." }, - "manager": { - "message": "Менеджар" - }, - "managerDesc": { - "message": "Менеджары могуць атрымліваць доступ і кіраваць прызначанымі калекцыямі ў вашай арганізацыі." - }, "all": { "message": "Усе" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Дазвол" }, - "managerPermissions": { - "message": "Дазволы менеджара" - }, - "adminPermissions": { - "message": "Дазволы адміністратара" - }, "accessEventLogs": { "message": "Доступ да журналаў з падзеямі" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Выдаліць любую калекцыю" }, - "manageAssignedCollections": { - "message": "Кіраванне прызначанымі калекцыямі" - }, "editAssignedCollections": { "message": "Рэдагаваць прызначаныя калекцыі" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Даць доступ да ўсіх бягучых і будучых калекцый." - }, - "accessAllCollectionsHelp": { - "message": "Калі пазначана, то гэта заменіць усе іншыя дазволы на калекцыю." - }, "selectMembers": { "message": "Выбраць удзельнікаў" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Група" }, - "groupAccessAll": { - "message": "Гэта група можа мець доступ і змяняць усе элементы." - }, - "memberAccessAll": { - "message": "Гэты ўдзельнік можа атрымліваць доступ і змяняць усе элементы." - }, "domainVerification": { "message": "Праверка дамена" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index b114f9da8cc..9de52f8744e 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Вписване" }, + "verifyIdentity": { + "message": "Потвърдете самоличността си" + }, "logInInitiated": { "message": "Вписването е стартирано" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Редови потребител с достъп до определени колекции в организацията." }, - "manager": { - "message": "Мениджър" - }, - "managerDesc": { - "message": "Мениджърите достъпват и управляват зададените им колекции в организацията." - }, "all": { "message": "Всички" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Право" }, - "managerPermissions": { - "message": "Права на управителя" - }, - "adminPermissions": { - "message": "Права на администратора" - }, "accessEventLogs": { "message": "Достъп до журналите" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Изтриване на всякакви колекции" }, - "manageAssignedCollections": { - "message": "Управление на възложените колекции" - }, "editAssignedCollections": { "message": "Редактиране на възложените колекции" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Можете да свързвате само колекции, които имате право да управлявате." }, - "accessAllCollectionsDesc": { - "message": "Дайте достъп до всички текущи и бъдещи колекции." - }, - "accessAllCollectionsHelp": { - "message": "Ако е избрано, това ще замени всички останали права свързани с колекцията." - }, "selectMembers": { "message": "Изберете членове" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Група" }, - "groupAccessAll": { - "message": "Тази група има достъп до всички записи и може да ги редактира." - }, - "memberAccessAll": { - "message": "Този член има достъп до всички записи и може да ги редактира." - }, "domainVerification": { "message": "Потвърждаване на домейн" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Потвърден" + }, + "viewSecret": { + "message": "Преглед на тайната" + }, + "noClients": { + "message": "Няма клиенти за показване" + }, + "providerBillingEmailHint": { + "message": "На този адрес ще бъдат изпращани всички фактури свързани с този доставчик", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index b58391e7546..d23a4fe90a1 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index fb5cc691cfe..a18b4afce8c 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index f0a50c38824..8a6337f9524 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Inicia sessió" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "S'ha iniciat la sessió" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Accediu i afegiu elements a les col·leccions assignades" }, - "manager": { - "message": "Gestor" - }, - "managerDesc": { - "message": "Creeu, suprimiu i gestioneu l'accés a les col·leccions assignades" - }, "all": { "message": "Tot" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permisos" }, - "managerPermissions": { - "message": "Permisos de l'administrador" - }, - "adminPermissions": { - "message": "Permisos de l'administrador" - }, "accessEventLogs": { "message": "Registres d'esdeveniments dels accessos" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Suprimeix alguna la col·lecció" }, - "manageAssignedCollections": { - "message": "Administra les col·leccions assignades" - }, "editAssignedCollections": { "message": "Edita col·leccions asignades" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Doneu accés a totes les col·leccions actuals i futures." - }, - "accessAllCollectionsHelp": { - "message": "Si està marcat, substituirà tots els altres permisos de la col·lecció." - }, "selectMembers": { "message": "Seleccioneu membres" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grup" }, - "groupAccessAll": { - "message": "Aquest grup pot accedir i modificar tots els elements." - }, - "memberAccessAll": { - "message": "Aquest usuari pot accedir i modificar tots els elements." - }, "domainVerification": { "message": "Verificació de dominis" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index c77dc3bdb96..bdfc78b0780 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Přihlásit se" }, + "verifyIdentity": { + "message": "Ověřte svou totožnost" + }, "logInInitiated": { "message": "Bylo zahájeno přihlášení" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Přistupuje k přiřazeným kolekcím a přidává je." }, - "manager": { - "message": "Správce" - }, - "managerDesc": { - "message": "Vytváří, maže a spravuje přístupy v přiřazených kolekcích." - }, "all": { "message": "Vše" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Oprávnění" }, - "managerPermissions": { - "message": "Oprávnění správce" - }, - "adminPermissions": { - "message": "Oprávnění administrátora" - }, "accessEventLogs": { "message": "Přístup k protokolům událostí" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Smazání jakékoli kolekce" }, - "manageAssignedCollections": { - "message": "Správa přiřazených kolekcí" - }, "editAssignedCollections": { "message": "Úprava přiřazených kolekcí" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Můžete přiřadit jen Vámi spravované kolekce." }, - "accessAllCollectionsDesc": { - "message": "Udělí přístup ke všem aktuálním i budoucím kolekcím." - }, - "accessAllCollectionsHelp": { - "message": "Pokud je zaškrtnuto, nahradí to všechna ostatní oprávnění ke kolekcím." - }, "selectMembers": { "message": "Vybrat členy" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Skupina" }, - "groupAccessAll": { - "message": "Tato skupina může vidět a upravovat vše." - }, - "memberAccessAll": { - "message": "Tento uživatel může vidět a upravovat vše." - }, "domainVerification": { "message": "Ověření domény" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Ověřeno" + }, + "viewSecret": { + "message": "Zobrazit tajný klíč" + }, + "noClients": { + "message": "Žádní klienti k zobrazení." + }, + "providerBillingEmailHint": { + "message": "Tato e-mailová adresa obdrží všechny faktury vztahující se k tomuto poskytovateli", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index 095e4dabca8..47560c86619 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index ff339e7a39e..2027f4a64b7 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log ind" }, + "verifyIdentity": { + "message": "Bekræft din identitet" + }, "logInInitiated": { "message": "Indlogning påbegyndt" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Tilgå og føj emner til tildelte samlinger" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Opret, slet og håndtér adgang i tildelte samlinger" - }, "all": { "message": "Alle" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Tilladelse" }, - "managerPermissions": { - "message": "Bestyrer-tilladelser" - }, - "adminPermissions": { - "message": "Admin-tilladelser" - }, "accessEventLogs": { "message": "Tilgå begivenhedslogger" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Slet enhver samling" }, - "manageAssignedCollections": { - "message": "Håndtér tildelte samlinger" - }, "editAssignedCollections": { "message": "Redigér tildelte samlinger" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Man kan kun tildele samlinger, man selv håndterer." }, - "accessAllCollectionsDesc": { - "message": "Tildel adgang til alle nuværende og fremtidige samlinger." - }, - "accessAllCollectionsHelp": { - "message": "Hvis afkrydset, erstatter dette alle andre samlingstilladelser." - }, "selectMembers": { "message": "Vælg medlemmer" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Gruppe" }, - "groupAccessAll": { - "message": "Denne gruppe kan tilgå og ændre alle emner." - }, - "memberAccessAll": { - "message": "Dette medlem kan tilgå og ændre alle emner." - }, "domainVerification": { "message": "Domænebekræftelse" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Bekræftet" + }, + "viewSecret": { + "message": "Vis hemmelighed" + }, + "noClients": { + "message": "Der er ingen klienter at vise" + }, + "providerBillingEmailHint": { + "message": "Denne e-mailadresse vil modtage alle fakturaer vedr. denne udbyder", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 6931b8345af..aa7c3d8dae7 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Anmelden" }, + "verifyIdentity": { + "message": "Verifiziere deine Identität" + }, "logInInitiated": { "message": "Anmeldung eingeleitet" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Kann auf Einträge zugewiesener Sammlungen zugreifen und neue hinzufügen" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Kann Einträge in zugewiesenen Sammlungen erstellen, löschen und Zugriff darauf verwalten" - }, "all": { "message": "Alle" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Berechtigung" }, - "managerPermissions": { - "message": "Manager-Berechtigungen" - }, - "adminPermissions": { - "message": "Administrator-Berechtigungen" - }, "accessEventLogs": { "message": "Zugriff auf Ereignisprotokolle" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Jede Sammlung löschen" }, - "manageAssignedCollections": { - "message": "Zugewiesene Sammlungen verwalten" - }, "editAssignedCollections": { "message": "Zugewiesene Sammlungen bearbeiten" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Du kannst nur von dir verwaltete Sammlungen zuweisen." }, - "accessAllCollectionsDesc": { - "message": "Gewähre Zugriff auf alle aktuellen und zukünftigen Sammlungen." - }, - "accessAllCollectionsHelp": { - "message": "Wenn aktiviert, ersetzt dies alle anderen Sammlungsberechtigungen." - }, "selectMembers": { "message": "Mitglieder auswählen" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Gruppe" }, - "groupAccessAll": { - "message": "Diese Gruppe darf auf alle Einträge zugreifen und diese ändern." - }, - "memberAccessAll": { - "message": "Dieses Mitglied darf auf alle Einträge zugreifen und diese ändern." - }, "domainVerification": { "message": "Domain-Verifizierung" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verifiziert" + }, + "viewSecret": { + "message": "Geheimnis anzeigen" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "Diese E-Mail-Adresse wird alle Rechnungen erhalten, die diesen Anbieter betreffen", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index b3dcdb0d94e..80465e702e9 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Είσοδος" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Η σύνδεση ξεκίνησε" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Ένας κανονικός χρήστης με πρόσβαση σε ανατεθείσες συλλογές στον οργανισμό σας." }, - "manager": { - "message": "Διαχειριστης" - }, - "managerDesc": { - "message": "Οι διαχειριστές μπορούν να έχουν πρόσβαση και να διαχειρίζονται εκχωρημένες συλλογές στον οργανισμό σας." - }, "all": { "message": "Όλα" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Δικαιώματα" }, - "managerPermissions": { - "message": "Δικαιώματα Manager" - }, - "adminPermissions": { - "message": "Δικαιώματα Διαχειριστή" - }, "accessEventLogs": { "message": "Αρχείο Καταγραφής Πρόσβασης" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Διαγραφή Οποιασδήποτε Συλλογής" }, - "manageAssignedCollections": { - "message": "Διαχείριση Αντιστοιχισμένων Συλλογών" - }, "editAssignedCollections": { "message": "Επεξεργασία Αντιστοιχισμένων Συλλογών" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 75054c1a7de..f817bc13580 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index 71226fb6177..9d2d8ed7b38 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "A regular user with access to assigned collections in your organisation." }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Managers can access and manage assigned collections in your organisation." - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access Event Logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage Assigned Collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 3d2e0d1e4d8..26c230a38d5 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Saluti" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Regula uzanto kun aliro al asignitaj kolektoj en via organizo." }, - "manager": { - "message": "Administranto" - }, - "managerDesc": { - "message": "Administrantoj povas aliri kaj administri asignitajn kolektojn en via organizo." - }, "all": { "message": "Ĉiuj" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Aliri Eventajn Registrojn" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Administri Asignitajn Kolektojn" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index f3fddf45bce..b0d6cbc70a8 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Identificarse" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Inicio de sesión en proceso" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Un usuario regular con acceso a las colecciones de su organización." }, - "manager": { - "message": "Gestor" - }, - "managerDesc": { - "message": "Los gestores pueden acceder y gestionar colecciones asignadas en tu organización." - }, "all": { "message": "Todo" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permiso" }, - "managerPermissions": { - "message": "Permisos del Administrador" - }, - "adminPermissions": { - "message": "Permisos del administrador" - }, "accessEventLogs": { "message": "Acceder a los registros de eventos" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Eliminar cualquier colección" }, - "manageAssignedCollections": { - "message": "Administrar colecciones asignadas" - }, "editAssignedCollections": { "message": "Editar colecciones asignadas" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Otorgar acceso a todas las colecciones actuales y futuras." - }, - "accessAllCollectionsHelp": { - "message": "Si está marcado, esto reemplazará todos los demás permisos de la colección." - }, "selectMembers": { "message": "Seleccionar miembros" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grupo" }, - "groupAccessAll": { - "message": "Este grupo puede acceder y modificar todos los elementos." - }, - "memberAccessAll": { - "message": "Este miembro puede acceder y modificar todos los elementos." - }, "domainVerification": { "message": "Verificación de dominio" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index 138351449a9..d19188f1acf 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Logi sisse" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Tavaline kasutaja, kel on ligipääsu organisatsiooni kirjetele." }, - "manager": { - "message": "Haldaja" - }, - "managerDesc": { - "message": "Administraatorid pääsevad ligi ja saavad hallata organisatsiooni poolt määratud kollektsioone." - }, "all": { "message": "Kõik" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Ligipääs sündmuste logile" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Kustutada mistahes kollektsiooni" }, - "manageAssignedCollections": { - "message": "Saab hallata määratud kollektsioone" - }, "editAssignedCollections": { "message": "Hallata määratud kollektsioone" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index 6a5e3782bc0..fa334f5aba5 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Hasi saioa" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Saioa hastea martxan da" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Erakundean esleitutako bildumetara sarbidea duen erabiltzaile erregularra." }, - "manager": { - "message": "Kudeatzailea" - }, - "managerDesc": { - "message": "Kudeatzaileek zure erakundean esleitutako bildumak eskuratu eta kudeatu ditzakete." - }, "all": { "message": "Guztiak" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Baimena" }, - "managerPermissions": { - "message": "Kudeatu baimenak" - }, - "adminPermissions": { - "message": "Kudeatzailearen baimenak" - }, "accessEventLogs": { "message": "Sarreren erregistroak" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Ezabatu edozein bilduma" }, - "manageAssignedCollections": { - "message": "Kudeatu esleitutako bildumak" - }, "editAssignedCollections": { "message": "Editatu esleitutako bildumak" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Taldea" }, - "groupAccessAll": { - "message": "Talde hau elementu guztietara sartu eta aldaketak egin ditzake." - }, - "memberAccessAll": { - "message": "Kide hau elementu guztietara sartu eta aldaketak egin ditzake." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index fe38a1e7e7e..ec607599741 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -579,16 +579,16 @@ "message": "دسترسی" }, "accessLevel": { - "message": "Access level" + "message": "سطح دسترسی" }, "accessing": { - "message": "Accessing" + "message": "در حال دسترسی" }, "loggedOut": { "message": "خارج شد" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "شما از اکانت خود خارج شده‌اید." }, "loginExpired": { "message": "نشست ورود شما منقضی شده است." @@ -722,6 +722,9 @@ "logIn": { "message": "ورود" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "ورود به سیستم آغاز شد" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "به مجموعه های اختصاص داده شده دسترسی داشته باشید و موارد را اضافه کنید" }, - "manager": { - "message": "مدیر" - }, - "managerDesc": { - "message": "ایجاد، حذف و مدیریت دسترسی در مجموعه های اختصاص داده شده" - }, "all": { "message": "همه" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "مجوز" }, - "managerPermissions": { - "message": "مدیریت مجوزها" - }, - "adminPermissions": { - "message": "مجوزهای مدیریت" - }, "accessEventLogs": { "message": "به گزارش‌های رویداد دسترسی داشته باشید" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "هر مجموعه ای را حذف کنید" }, - "manageAssignedCollections": { - "message": "مدیریت مجموعه های اختصاص داده شده" - }, "editAssignedCollections": { "message": "ویرایش مجموعه های اختصاص داده شده" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "اجازه دسترسی به تمام مجموعه‌های فعلی و آینده." - }, - "accessAllCollectionsHelp": { - "message": "اگر علامت زده شود، این گزینه جایگزین سایر مجوزهای مجموعه می‌شود." - }, "selectMembers": { "message": "انتخاب اعضا" }, @@ -6717,12 +6699,6 @@ "group": { "message": "گروه" }, - "groupAccessAll": { - "message": "این گروه می‌تواند به همه موارد دسترسی داشته باشد و آن‌ها را تغییر دهد." - }, - "memberAccessAll": { - "message": "این عضو می‌تواند به همه موارد دسترسی داشته باشد و آن‌ها را تغییر دهد." - }, "domainVerification": { "message": "تائید دامنه" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 2347c83d0d5..162f436b207 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Kirjaudu sisään" }, + "verifyIdentity": { + "message": "Vahvista henkilöllisyytesi" + }, "logInInitiated": { "message": "Kirjautuminen aloitettu" }, @@ -1054,10 +1057,10 @@ "message": "Kopioi UUID" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Käyttötunnisteen päivitysvirhe" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Päivitystunnistetta tai API-avaimia ei löytynyt. Kokeile kirjautua ulos ja takaisin sisään." }, "warning": { "message": "Varoitus" @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Voi käyttää määritettyjen kokoelmien kohteita ja lisätä niitä." }, - "manager": { - "message": "Valvoja" - }, - "managerDesc": { - "message": "Voi luoda, poistaa ja hallita määritettyjen kokoelmien käyttöoikeuksia." - }, "all": { "message": "Kaikki" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Käyttöoikeus" }, - "managerPermissions": { - "message": "Valvojan oikeudet" - }, - "adminPermissions": { - "message": "Ylläpitäjän oikeudet" - }, "accessEventLogs": { "message": "Tapahtumalokien käyttö" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Poista kokoelmia" }, - "manageAssignedCollections": { - "message": "Kokoelmamääritysten hallinta" - }, "editAssignedCollections": { "message": "Muokkaa kokoelmamäärityksiä" }, @@ -5599,16 +5587,16 @@ "message": "itse ylläpidetty" }, "customEnvironment": { - "message": "Custom environment" + "message": "Mukautettu palvelinympäristö" }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Määritä itse ylläpitämäsi Bitwarden-asennuksen perusosoite. Esimerkki: https://bitwarden.yritys.fi." }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Edistynyttä määritystä varten voit syöttää jokaisen palvelun perusosoitteen erikseen." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Sinun on lisättävä joko palvelimen perusosoite tai ainakin yksi mukautettu palvelinympäristö." }, "apiUrl": { "message": "API-palvelimen URL" @@ -5915,7 +5903,7 @@ } }, "forwaderInvalidToken": { - "message": "Virheellinen $SERVICENAME$ -rajapinnan tunniste", + "message": "Virheellinen $SERVICENAME$ API -tunniste", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -5925,7 +5913,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Virheellinen $SERVICENAME$ -rajapinnan tunniste: $ERRORMESSAGE$", + "message": "Virheellinen $SERVICENAME$ API -tunniste: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Voit määrittää vain hallitsemiasi kokoelmia." }, - "accessAllCollectionsDesc": { - "message": "Myönnä käyttöoikeudet kaikkiin nykyisiin ja tuleviin kokoelmiin" - }, - "accessAllCollectionsHelp": { - "message": "Jos valittu, korvataan kaikki muut kokoelmien käyttöoikeudet." - }, "selectMembers": { "message": "Valitse jäsenet" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Ryhmä" }, - "groupAccessAll": { - "message": "Tämä ryhmä voi tarkastella ja muokata kaikkia kohteita." - }, - "memberAccessAll": { - "message": "Tämä jäsen voi tarkastella ja muokata kaikkia kohteita." - }, "domainVerification": { "message": "Verkkotunnusvarmennus" }, @@ -8119,7 +8095,7 @@ "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "unassignedItemsBannerCTAPartTwo": { - "message": ", jotta ne näkyvät.", + "message": "ista, jotta ne näkyvät.", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "deleteProvider": { @@ -8296,10 +8272,10 @@ "message": "Et ole valinnut yhtään kokoelmaa." }, "updateName": { - "message": "Päivitä nimi" + "message": "Vaihda nimi" }, "updatedOrganizationName": { - "message": "Päivitetty organisaation nimi" + "message": "Organisaation nimi vaihdettiin" }, "providerPlan": { "message": "Hallittu palvelutoimittaja" @@ -8347,12 +8323,22 @@ "message": "Bitcoin" }, "updatedTaxInformation": { - "message": "Päivitetyt verotiedot" + "message": "Verotiedot vaihdettiin" }, "unverified": { "message": "Vahvistamaton" }, "verified": { "message": "Vahvistettu" + }, + "viewSecret": { + "message": "Näytä salaisuus" + }, + "noClients": { + "message": "Näytettäviä päätteitä ei ole" + }, + "providerBillingEmailHint": { + "message": "Tämä sähköpostiosoite vastaanottaa kaikki tähän palveluntarjoajaan liittyvät 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." } } diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index b73d6af58ff..197dd34d3a9 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Mag-log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Sinimulan ang pag-log in" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access at magdagdag ng mga item sa mga nakatalagang koleksyon" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Lumikha, magtanggal, at pamahalaan ang pag access sa mga nakatalagang koleksyon" - }, "all": { "message": "Lahat" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Pahintulot" }, - "managerPermissions": { - "message": "Mga Pahintulot ng Manager" - }, - "adminPermissions": { - "message": "Mga Pahintulot ng Admin" - }, "accessEventLogs": { "message": "Access ang mga log ng kaganapan" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Tanggalin ang anumang koleksyon" }, - "manageAssignedCollections": { - "message": "Pamahalaan ang mga nakatalagang koleksyon" - }, "editAssignedCollections": { "message": "I-edit ang mga nakatalagang koleksyon" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Magbigay ng access sa lahat ng kasalukuyan at hinaharap na mga koleksyon." - }, - "accessAllCollectionsHelp": { - "message": "Kung titingnan, papalitan nito ang lahat ng iba pang mga pahintulot sa koleksyon." - }, "selectMembers": { "message": "Pumili ng mga miyembro" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grupo" }, - "groupAccessAll": { - "message": "Maaaring ma-access at baguhin ng grupong ito ang lahat ng item." - }, - "memberAccessAll": { - "message": "Maaaring ma-access at baguhin ng miyembrong ito ang lahat ng item." - }, "domainVerification": { "message": "Pagpapatunay ng domain" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index 1c1191476ee..ecf1d323f32 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Se connecter" }, + "verifyIdentity": { + "message": "Vérifiez votre Identité" + }, "logInInitiated": { "message": "Connexion initiée" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Un utilisateur normal avec accès aux collections de votre organisation." }, - "manager": { - "message": "Gestionnaire" - }, - "managerDesc": { - "message": "Les gestionnaires peuvent voir et gérer les collections de votre organisation qui leur ont été assignées." - }, "all": { "message": "Tous" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Permissions du Gestionnaire" - }, - "adminPermissions": { - "message": "Permissions de l'Administrateur" - }, "accessEventLogs": { "message": "Accéder aux journaux d'événements" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Supprimer n'importe quelle collection" }, - "manageAssignedCollections": { - "message": "Gérer les collections assignées" - }, "editAssignedCollections": { "message": "Modifier les collection assignées" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Vous pouvez seulement assigner les collections que vous gérez." }, - "accessAllCollectionsDesc": { - "message": "Accorder l'accès à toutes les collections actuelles et futures." - }, - "accessAllCollectionsHelp": { - "message": "Si coché, cela remplacera toutes les autres autorisations de collection." - }, "selectMembers": { "message": "Sélectionner les membres" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Groupe" }, - "groupAccessAll": { - "message": "Ce groupe peut accéder et modifier tous les éléments." - }, - "memberAccessAll": { - "message": "Ce groupe peut voir et modifier tous les éléments." - }, "domainVerification": { "message": "Vérification du domaine" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Vérifié" + }, + "viewSecret": { + "message": "Afficher le secret" + }, + "noClients": { + "message": "Il n'y a aucun client à afficher" + }, + "providerBillingEmailHint": { + "message": "Cette adresse courriel recevra toutes les factures relatives à ce fournisseur", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index b34ccbb9013..9363c432ca2 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 6eae24eee0f..a10ee46547b 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "התחבר" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "משתמש רגיל עם גישה לאוספים נבחרים בארגון שלך." }, - "manager": { - "message": "מנהל" - }, - "managerDesc": { - "message": "מנהלים יכולים לגשת ולנהל אוספים נבחרים בארגונך." - }, "all": { "message": "הכל" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 21cabab4b5f..01a719bfb30 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index ba98ea021f8..df6f3aa7381 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Prijavi se" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Pokrenuta prijava" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Pristupi i dodaj stavke dodijeljenim zbirkama" }, - "manager": { - "message": "Upravitelj" - }, - "managerDesc": { - "message": "Stvori, obriši i upravljaj pristupom u dodijeljenim zbirkama" - }, "all": { "message": "Sve" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Dopuštenje" }, - "managerPermissions": { - "message": "Dopuštenja upravitelja" - }, - "adminPermissions": { - "message": "Dopuštenja administratora" - }, "accessEventLogs": { "message": "Pristup zapisnicima događaja" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Obriši zbirku" }, - "manageAssignedCollections": { - "message": "Upravljanje dodijeljenim zbirkama" - }, "editAssignedCollections": { "message": "Uredi dodijeljene zbirke" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Odobri pristup svim postojećim i budućim zbirkama." - }, - "accessAllCollectionsHelp": { - "message": "Ako je uključeno, ovo će zamijeniti sve druge dozvole za prikupljanje." - }, "selectMembers": { "message": "Odaberi članove" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grupa" }, - "groupAccessAll": { - "message": "Ova grupa može pristupiti i urediti sve stavke." - }, - "memberAccessAll": { - "message": "Ovaj korisnik može pristupiti i urediti sve stavke." - }, "domainVerification": { "message": "Potvrda domene" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 1371ceb262f..05f4221ab1b 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Bejelentkezés" }, + "verifyIdentity": { + "message": "Személyazonosság ellenőrzése" + }, "logInInitiated": { "message": "A bejelentkezés elindításra került." }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Normál felhasználó a szervezeti gyűjtemények elérésével." }, - "manager": { - "message": "Menedzser" - }, - "managerDesc": { - "message": "A menedzserek hozzáférhetnek a szervezet összes gyűjteményéhez, valamint kezelhetik azokat." - }, "all": { "message": "Összes" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Jogosultság" }, - "managerPermissions": { - "message": "Jogosultságok kezelése" - }, - "adminPermissions": { - "message": "Adminisztrátori jogosultságok" - }, "accessEventLogs": { "message": "Eseménynapló elérése" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Bármely gyűjtemény törlése" }, - "manageAssignedCollections": { - "message": "Hozzárendelt gyűjtemények kezelése" - }, "editAssignedCollections": { "message": "Hozzárendelt gyűjtemények szerkesztése" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Csak a saját kezelésű gyűjteményeket lehet hozzárendelni." }, - "accessAllCollectionsDesc": { - "message": "Hozzáférés kiosztása az összes jelenlegi és jövőbeli gyűjteményhez." - }, - "accessAllCollectionsHelp": { - "message": "Bejelöllve lecseréli az összes gyűjtemény jogosultságot." - }, "selectMembers": { "message": "Tagok kválasztása" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Csoport" }, - "groupAccessAll": { - "message": "A csoport elérheti és módosíthatja az összes elemet." - }, - "memberAccessAll": { - "message": "Ez a felhasználó minden elemhez hozzáférhet és módosíthatja az összes elemet." - }, "domainVerification": { "message": "Domain ellenőrzés" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Ellenőrzött" + }, + "viewSecret": { + "message": "Titkos kód megtekintése" + }, + "noClients": { + "message": "Nincsenek listázandó ügyfelek." + }, + "providerBillingEmailHint": { + "message": "Erre az email címre érkezik az ehhez a szolgáltatóhoz kapcsolódó összes számla.", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index c481ca8a095..bdb5d731d75 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Masuk" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Pengguna biasa dengan akses ke koleksi yang ditetapkan di organisasi Anda." }, - "manager": { - "message": "Pengelola" - }, - "managerDesc": { - "message": "Manajer dapat mengakses dan mengelola koleksi yang ditetapkan di organisasi Anda." - }, "all": { "message": "Semua" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Izin" }, - "managerPermissions": { - "message": "Pengelola Izin" - }, - "adminPermissions": { - "message": "Izin Admin" - }, "accessEventLogs": { "message": "Akses Log Peristiwa" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Hapus Koleksi" }, - "manageAssignedCollections": { - "message": "Kelola Koleksi yang Ditugaskan" - }, "editAssignedCollections": { "message": "Edit koleksi yang ditetapkan" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 192115c13f9..05bb5c7a2d0 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Accedi" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Login avviato" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Accedi e aggiungi elementi alle raccolte assegnate" }, - "manager": { - "message": "Responsabile" - }, - "managerDesc": { - "message": "Crea, elimina, e gestisci l'accesso nelle raccolte assegnate" - }, "all": { "message": "Tutti" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permesso" }, - "managerPermissions": { - "message": "Permessi del manager" - }, - "adminPermissions": { - "message": "Permesso dell'amministratore" - }, "accessEventLogs": { "message": "Accedi al registro degli eventi" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Elimina tutte le raccolte" }, - "manageAssignedCollections": { - "message": "Gestisci le raccolte assegnate" - }, "editAssignedCollections": { "message": "Modifica le raccolte assegnate" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Puoi assegnare solo le raccolte che gestisci." }, - "accessAllCollectionsDesc": { - "message": "Concedi accesso a tutte le raccolte esistenti e future." - }, - "accessAllCollectionsHelp": { - "message": "Se attivato, sostituirà tutte le altre autorizzazioni per le raccolte." - }, "selectMembers": { "message": "Seleziona membri" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Gruppo" }, - "groupAccessAll": { - "message": "Questo gruppo può accedere e modificare tutti gli elementi." - }, - "memberAccessAll": { - "message": "Questo membro può accedere e modificare tutti gli elementi." - }, "domainVerification": { "message": "Verifica del dominio" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verificato" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index a1f71ef90b9..8634304a934 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "ログイン" }, + "verifyIdentity": { + "message": "本人確認" + }, "logInInitiated": { "message": "ログイン開始" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "あなたの組織に割り当てられたコレクションへのアクセス権を持つ標準ユーザーです。" }, - "manager": { - "message": "マネージャー" - }, - "managerDesc": { - "message": "マネージャーは組織内の割り当てられたコレクションへアクセスし管理することができます。" - }, "all": { "message": "すべて" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "権限" }, - "managerPermissions": { - "message": "管理者権限" - }, - "adminPermissions": { - "message": "管理者権限" - }, "accessEventLogs": { "message": "イベントログにアクセス" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "任意のコレクションを削除" }, - "manageAssignedCollections": { - "message": "割り当てられたコレクションの管理" - }, "editAssignedCollections": { "message": "割り当てられたコレクションを編集" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "自分が管理しているコレクションのみを割り当てることができます。" }, - "accessAllCollectionsDesc": { - "message": "現在および将来のすべてのコレクションへのアクセスを許可します。" - }, - "accessAllCollectionsHelp": { - "message": "チェックされている場合、他のすべてのコレクション権限が置き換えられます。" - }, "selectMembers": { "message": "メンバーを選択" }, @@ -6717,12 +6699,6 @@ "group": { "message": "グループ" }, - "groupAccessAll": { - "message": "このグループはすべてのアイテムにアクセスして変更できます。" - }, - "memberAccessAll": { - "message": "このメンバーはすべてのアイテムにアクセスして変更できます。" - }, "domainVerification": { "message": "ドメイン検証" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "認証済み" + }, + "viewSecret": { + "message": "シークレットを表示" + }, + "noClients": { + "message": "一覧表示するクライアントがありません" + }, + "providerBillingEmailHint": { + "message": "このメールアドレスは、このプロバイダに関連するすべての請求書を受信します", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index e5697457baf..db176fa8bbb 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "ავტორიზაცია" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "ავტორიზაცია დაწყებულია" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index b34ccbb9013..9363c432ca2 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index 0ab6aa294dc..fdb5c19ce7e 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "ಲಾಗಿನ್" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "ನಿಮ್ಮ ಸಂಸ್ಥೆಯಲ್ಲಿ ನಿಯೋಜಿಸಲಾದ ಸಂಗ್ರಹಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುವ ಸಾಮಾನ್ಯ ಬಳಕೆದಾರ." }, - "manager": { - "message": "ವ್ಯವಸ್ಥಾಪಕ" - }, - "managerDesc": { - "message": "ನಿಮ್ಮ ಸಂಸ್ಥೆಯಲ್ಲಿ ನಿಯೋಜಿತ ಸಂಗ್ರಹಣೆಯನ್ನು ವ್ಯವಸ್ಥಾಪಕರು ಪ್ರವೇಶಿಸಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು." - }, "all": { "message": "ಎಲ್ಲಾ" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "ಈವೆಂಟ್ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "ನಿಯೋಜಿಸಲಾದ ಸಂಗ್ರಹಗಳನ್ನು ನಿರ್ವಹಿಸಿ" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 4fb8aa34212..c91fe4f7d27 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "로그인" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "조직 내 할당된 컬렉션에 액세스할 수 있는 일반 사용자." }, - "manager": { - "message": "관리자" - }, - "managerDesc": { - "message": "관리자는 조직 내 할당된 컬렉션에 액세스하고 관리할 수 있습니다." - }, "all": { "message": "모두" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "이벤트 로그 접근" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "아무 컬렉션 삭제" }, - "manageAssignedCollections": { - "message": "할당된 컬렉션 관리" - }, "editAssignedCollections": { "message": "할당된 컬렉션 수정" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "구성원 선택" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "이 구성원은 모든 항목에 접근 및 수정이 가능합니다." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 7a5f85fa918..333a655ab9e 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -588,7 +588,7 @@ "message": "Atteicies" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Notika izrakstīšanās no Tava konta." }, "loginExpired": { "message": "Pieteikšanās sesija ir beigusies." @@ -722,6 +722,9 @@ "logIn": { "message": "Pieteikties" }, + "verifyIdentity": { + "message": "Apliecināt savu identitāti" + }, "logInInitiated": { "message": "Uzsākta pieteikšanās" }, @@ -1054,10 +1057,10 @@ "message": "Ievietot UUID starpliktuvē" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Piekļuves pilnvaras atsvaizināšanas kļūda" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Netika atrastas atsvaidzināšanas pilnvaras vai API atslēgas. Lūgums mēģināt izrakstīties un atkal pieteikties." }, "warning": { "message": "Brīdinājums" @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Parasts lietotājs ar piekļuvi piešķirtajiem apvienības krājumiem." }, - "manager": { - "message": "Pārvaldnieks" - }, - "managerDesc": { - "message": "Vadītāji var piekļūt un pārvaldīt piešķirtos apvienības krājumus." - }, "all": { "message": "Visi" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Atļauja" }, - "managerPermissions": { - "message": "Pārvaldnieka atļaujas" - }, - "adminPermissions": { - "message": "Administratora atļaujas" - }, "accessEventLogs": { "message": "Piekļūt notikumu žurnāla ierakstiem" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Izdzēst jebkuru kolekciju" }, - "manageAssignedCollections": { - "message": "Pārvaldīt norīkotos krājumus" - }, "editAssignedCollections": { "message": "Labot norīkotos krājumus" }, @@ -5596,37 +5584,37 @@ "message": "Norēķinu sinhronizācijas pilnvaras nomaiņa padarīs nederīgu iepriekšējo." }, "selfHostedServer": { - "message": "self-hosted" + "message": "pašizvietots" }, "customEnvironment": { - "message": "Custom environment" + "message": "Pielāgota vide" }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Jānorāda sava pašizvietotā Bitward servera pamata URL. Piemērs: https://bitwarden.uznemums.lv" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Papildu konfigurācijā ir iespējams norādīt URL katram pakalpojumam atsevišķi." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Jāpievieno vai no servera pamata URL vai vismaz viena pielāgota vide." }, "apiUrl": { - "message": "API server URL" + "message": "API servera URL" }, "webVaultUrl": { - "message": "Web vault server URL" + "message": "Tīmekļa glabātavas servera URL" }, "identityUrl": { - "message": "Identity server URL" + "message": "Identitātes servera URL" }, "notificationsUrl": { - "message": "Notifications server URL" + "message": "Paziņojumu servera URL" }, "iconsUrl": { - "message": "Icons server URL" + "message": "Ikonu servera URL" }, "environmentSaved": { - "message": "Environment URLs saved" + "message": "Vides URL saglabāti" }, "selfHostingTitle": { "message": "Pašizvietošana" @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Var piešķirt tikai pārvaldītos krājumus." }, - "accessAllCollectionsDesc": { - "message": "Piešķirt piekļuvi visiem pašreizējiem un turpmākajiem krājumiem." - }, - "accessAllCollectionsHelp": { - "message": "Ja atzīmēts, tiks aizstātas visas citas krājumu atļaujas." - }, "selectMembers": { "message": "Atlasīt dalībniekus" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Kopa" }, - "groupAccessAll": { - "message": "Šī kopa var piekļūt visiem vienumiem un mainīt tos." - }, - "memberAccessAll": { - "message": "Šis dalībnieks var piekļūt visiem vienumiem un mainīt tos." - }, "domainVerification": { "message": "Domēna apstiprināšana" }, @@ -8347,12 +8323,22 @@ "message": "Bitcoin" }, "updatedTaxInformation": { - "message": "Updated tax information" + "message": "Atjaunināta nodokļu informācija" }, "unverified": { - "message": "Unverified" + "message": "Neapliecināts" }, "verified": { - "message": "Verified" + "message": "Apliecināts" + }, + "viewSecret": { + "message": "Skatīt noslēpumu" + }, + "noClients": { + "message": "Nav klientu, ko parādīt" + }, + "providerBillingEmailHint": { + "message": "Uz šo e-pasta adresi tiks nosūtīti visi ar šo nodrošinātāju saistītie rēķini", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index e05b1a15918..dd27f78c2a5 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "പ്രവേശിക്കുക" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "നിങ്ങളുടെ ഓർഗനൈസേഷനിൽ നിയുക്ത ശേഖരങ്ങളിലേക്ക് ആക്‌സസ് ഉള്ള ഒരു സാധാരണ ഉപയോക്താവ്." }, - "manager": { - "message": "മാനേജർ" - }, - "managerDesc": { - "message": "മാനേജർമാർക്ക് നിങ്ങളുടെ ഓർഗനൈസേഷനിൽ നിയുക്ത ശേഖരങ്ങൾ ആക്‌സസ് ചെയ്യാനും നിയന്ത്രിക്കാനും കഴിയും." - }, "all": { "message": "എല്ലാം" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index b34ccbb9013..9363c432ca2 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index b34ccbb9013..9363c432ca2 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index 1ebfb3f0031..a3cdec7bcd3 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Logg på" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Pålogging startet" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "En vanlig bruker med tilgang til tilegnede samlinger i din organisasjon." }, - "manager": { - "message": "Behandler" - }, - "managerDesc": { - "message": "Behandlere har tilgang til og kan behandle tilegnede samlinger i din organisasjon." - }, "all": { "message": "Alle" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Tillatelse" }, - "managerPermissions": { - "message": "Ledertillatelser" - }, - "adminPermissions": { - "message": "Admin-tillatelser" - }, "accessEventLogs": { "message": "Få tilgang til hendelseslogger" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Slett enhver samling" }, - "manageAssignedCollections": { - "message": "Administrer alle tildelte samlinger" - }, "editAssignedCollections": { "message": "Rediger tildelte samlinger" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Gi tilgang til alle nåværende og fremtidige samlinger." - }, - "accessAllCollectionsHelp": { - "message": "Hvis merket av, vil dette erstatte alle andre samlingstillatelser." - }, "selectMembers": { "message": "Velg medlemmer" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Gruppe" }, - "groupAccessAll": { - "message": "Denne gruppen har tilgang til og kan endre alle elementer." - }, - "memberAccessAll": { - "message": "Dette medlemmet har tilgang til og kan endre alle elementer." - }, "domainVerification": { "message": "Domenebekreftelse" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index 30be37fe071..4d8dfbbb103 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index fac7616a090..bb64a2fe2a3 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Inloggen" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Inloggen gestart" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Een standaardgebruiker met toegang tot de verzamelingen van je organisatie." }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Managers hebben toegang tot toegewezen verzamelingen binnen je organisatie en kunnen deze ook beheren." - }, "all": { "message": "Alle" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Toestemming" }, - "managerPermissions": { - "message": "Managersrechten" - }, - "adminPermissions": { - "message": "Beheerdersrechten" - }, "accessEventLogs": { "message": "Eventlogs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Iedere verzameling verwijderen" }, - "manageAssignedCollections": { - "message": "Toegewezen collecties beheren" - }, "editAssignedCollections": { "message": "Toegewezen verzamelingen bewerken" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Geef toegang tot alle huidige en toekomstige collecties." - }, - "accessAllCollectionsHelp": { - "message": "Indien aangevinkt, vervangt dit alle andere rechten op collecties." - }, "selectMembers": { "message": "Leden selecteren" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Groep" }, - "groupAccessAll": { - "message": "Deze groep kan alle items inzien en bewerken." - }, - "memberAccessAll": { - "message": "Deze gebruiker kan alle items inzien en bewerken." - }, "domainVerification": { "message": "Domeinverificatie" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "Geheim weergeven" + }, + "noClients": { + "message": "Er zijn geen weer te geven clients" + }, + "providerBillingEmailHint": { + "message": "Dit e-mailadres ontvangt alle facturen van deze provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index bc3bd862ed5..206989208d7 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index b34ccbb9013..9363c432ca2 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index be31574e754..4709a5686fc 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Zaloguj się" }, + "verifyIdentity": { + "message": "Zweryfikuj swoją tożsamość" + }, "logInInitiated": { "message": "Logowanie rozpoczęte" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Standardowy użytkownik, posiadający dostęp do kolekcji w Twojej organizacji." }, - "manager": { - "message": "Menedżer" - }, - "managerDesc": { - "message": "Menedżerowie mogą uzyskiwać dostęp do przypisanych kolekcji i zarządzać nimi w organizacji." - }, "all": { "message": "Wszyscy" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Uprawnienie" }, - "managerPermissions": { - "message": "Menedżer uprawnień" - }, - "adminPermissions": { - "message": "Administrator uprawnień" - }, "accessEventLogs": { "message": "Dostęp do dziennika zdarzeń" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Usuń dowolną kolekcję" }, - "manageAssignedCollections": { - "message": "Zarządzaj przypisanymi kolekcjami" - }, "editAssignedCollections": { "message": "Edytuj przypisane kolekcje" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Możesz przypisać tylko kolekcje, którymi zarządzasz." }, - "accessAllCollectionsDesc": { - "message": "Udziel dostępu do wszystkich bieżących i przyszłych kolekcji." - }, - "accessAllCollectionsHelp": { - "message": "Jeśli zaznaczone, zastąpi to wszystkie inne uprawnienia kolekcji." - }, "selectMembers": { "message": "Wybierz członków" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grupa" }, - "groupAccessAll": { - "message": "Ta grupa może wyświetlać i modyfikować wszystkie elementy." - }, - "memberAccessAll": { - "message": "Ten użytkownik może wyświetlać i modyfikować wszystkie elementy." - }, "domainVerification": { "message": "Weryfikacja domeny" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Zweryfikowane" + }, + "viewSecret": { + "message": "Zobacz sekret" + }, + "noClients": { + "message": "Brak klientów do wyświetlenia" + }, + "providerBillingEmailHint": { + "message": "Ten adres e-mail otrzyma wszystkie faktury dotyczące tego dostawcy", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 81f0fab1496..dd962b3311d 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Iniciar sessão" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Login iniciado" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Um usuário comum com acesso às coleções da sua organização." }, - "manager": { - "message": "Gerente" - }, - "managerDesc": { - "message": "Os gerentes podem acessar e gerenciar coleções atribuídas em sua organização." - }, "all": { "message": "Todos" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permissão" }, - "managerPermissions": { - "message": "Permissões de Gerente" - }, - "adminPermissions": { - "message": "Permissões de Administrador" - }, "accessEventLogs": { "message": "Acessar Registro de Eventos" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Excluir Qualquer Coleção" }, - "manageAssignedCollections": { - "message": "Gerenciar Coleções Atribuídas" - }, "editAssignedCollections": { "message": "Editar Coleções Atribuídas" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Você só pode atribuir coleções que você gerencia." }, - "accessAllCollectionsDesc": { - "message": "Conceder acesso a todas as coleções atuais e futuras." - }, - "accessAllCollectionsHelp": { - "message": "Se marcado, isto irá substituir todas as permissões de outras coleções." - }, "selectMembers": { "message": "Selecionar membros" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grupo" }, - "groupAccessAll": { - "message": "Este grupo pode acessar e modificar todos os itens." - }, - "memberAccessAll": { - "message": "Este usuário pode acessar e modificar todos os itens." - }, "domainVerification": { "message": "Verificação de Domínio" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 617e7e67af1..c286b8ee0b2 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Iniciar sessão" }, + "verifyIdentity": { + "message": "Verifique a sua identidade" + }, "logInInitiated": { "message": "A preparar o início de sessão" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Aceder e adicionar itens às coleções atribuídas" }, - "manager": { - "message": "Gestor" - }, - "managerDesc": { - "message": "Criar, eliminar e gerir o acesso a coleções atribuídas" - }, "all": { "message": "Todos" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permissão" }, - "managerPermissions": { - "message": "Permissões do gestor" - }, - "adminPermissions": { - "message": "Permissões do administrador" - }, "accessEventLogs": { "message": "Aceder aos registos de eventos" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Eliminar qualquer coleção" }, - "manageAssignedCollections": { - "message": "Gerir coleções atribuídas" - }, "editAssignedCollections": { "message": "Editar coleções atribuídas" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Só pode atribuir coleções que gere." }, - "accessAllCollectionsDesc": { - "message": "Conceder acesso a todas as coleções atuais e futuras." - }, - "accessAllCollectionsHelp": { - "message": "Se estiver selecionada, esta opção substitui todas as outras permissões de coleção." - }, "selectMembers": { "message": "Selecionar membros" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grupo" }, - "groupAccessAll": { - "message": "Este grupo pode aceder e modificar todos os itens." - }, - "memberAccessAll": { - "message": "Este membro pode aceder e modificar todos os itens." - }, "domainVerification": { "message": "Verificação do domínio" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verificado" + }, + "viewSecret": { + "message": "Ver segredo" + }, + "noClients": { + "message": "Não existem clientes para listar" + }, + "providerBillingEmailHint": { + "message": "Este endereço de e-mail receberá todas as faturas relativas a este fornecedor", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index d0c7e7a0f77..282428e7cb2 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Conectare" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Autentificare inițiată" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Un utilizator obișnuit cu acces la colecțiile alocate din organizația dvs." }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Managerii pot accesa și gestiona colecțiile atribuite în organizația dvs." - }, "all": { "message": "Tot" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Permisiuni manager" - }, - "adminPermissions": { - "message": "Permisiuni Admin" - }, "accessEventLogs": { "message": "Accesare jurnale evenimente" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Ștergere a oricărei colecții" }, - "manageAssignedCollections": { - "message": "Gestionare a colecțiilor alocate" - }, "editAssignedCollections": { "message": "Editare a colecțiilor atribuite" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index 51275705380..6b74ddfbcf8 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Войти" }, + "verifyIdentity": { + "message": "Подтвердите вашу личность" + }, "logInInitiated": { "message": "Вход инициирован" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Доступ и добавление элементов в соответствующие коллекции" }, - "manager": { - "message": "Менеджер" - }, - "managerDesc": { - "message": "Создание, удаление и управление доступом в соответствующих коллекциях" - }, "all": { "message": "Все" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Разрешение" }, - "managerPermissions": { - "message": "Разрешения менеджера" - }, - "adminPermissions": { - "message": "Разрешения администратора" - }, "accessEventLogs": { "message": "Доступ к журналам событий" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Удалять любую коллекцию" }, - "manageAssignedCollections": { - "message": "Управлять назначенными коллекциями" - }, "editAssignedCollections": { "message": "Изменять назначенные коллекции" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Вы можете назначать только те коллекции, которыми управляете." }, - "accessAllCollectionsDesc": { - "message": "Предоставить доступ ко всем текущим и будущим коллекциям." - }, - "accessAllCollectionsHelp": { - "message": "Если отмечено, это заменит все остальные разрешения на коллекцию." - }, "selectMembers": { "message": "Выбрать участников" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Группа" }, - "groupAccessAll": { - "message": "Эта группа может иметь доступ и изменять все элементы." - }, - "memberAccessAll": { - "message": "Эта пользователь может иметь доступ и изменять все элементы." - }, "domainVerification": { "message": "Верификация домена" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Верифицирован" + }, + "viewSecret": { + "message": "Просмотреть секрет" + }, + "noClients": { + "message": "Нет клиентов для отображения" + }, + "providerBillingEmailHint": { + "message": "На этот адрес email будут приходить все счета, относящиеся к данному провайдеру", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index e0cd81be1b1..8e3c04cf62f 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "පිවිසෙන්න" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 1bf83692b6b..93c03e6f507 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Prihlásiť sa" }, + "verifyIdentity": { + "message": "Overte svoju totožnosť" + }, "logInInitiated": { "message": "Iniciované prihlásenie" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Obyčajný používateľ s prístupom k zbierkam organizácie." }, - "manager": { - "message": "Manažér" - }, - "managerDesc": { - "message": "Manažéri môžu pristupovať k a spravovať pridelené zbierky v organizácii." - }, "all": { "message": "Všetky" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Oprávnenie" }, - "managerPermissions": { - "message": "Oprávnenia manažéra" - }, - "adminPermissions": { - "message": "Oprávnenia správcu" - }, "accessEventLogs": { "message": "Prístup k protokolom udalostí" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Odstrániť ľubovoľnú zbierku" }, - "manageAssignedCollections": { - "message": "Spravovať priradené zbierky" - }, "editAssignedCollections": { "message": "Upraviť priradené zbierky" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Prideliť môžete iba zbierky ktoré spravujete." }, - "accessAllCollectionsDesc": { - "message": "Povoliť prístup k všetkým súčasným a budúcim zbierkam." - }, - "accessAllCollectionsHelp": { - "message": "Zaškrtnutím nahradíte všetky ostatné povolenia ku zbierke." - }, "selectMembers": { "message": "Vybrať členov" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Skupina" }, - "groupAccessAll": { - "message": "Táto skupina môže upravovať a pristupovať k všetkým položkám." - }, - "memberAccessAll": { - "message": "Tento člen môže upravovať a pristupovať k všetkým položkám." - }, "domainVerification": { "message": "Overenie domény" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Overený" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "Neexistujú žiadni klienti na zobrazenie" + }, + "providerBillingEmailHint": { + "message": "Na túto e-mailovú adresu budú zasielané všetky faktúry týkajúce sa tohto poskytovateľa", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index a14b2beb117..9648610d395 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Prijava" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Prijava se je začela" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "Vsi" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Preverjanje domene" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index d120e1bb4b8..2379d2561a0 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Пријавите се" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Пријава је покренута" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Редовни корисник са приступом додељеним колекцијама у вашој организацији." }, - "manager": { - "message": "Менаџер" - }, - "managerDesc": { - "message": "Менаџери могу да приступе додељеним колекцијама и управљају њима у вашој организацији." - }, "all": { "message": "Све" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Дозвола" }, - "managerPermissions": { - "message": "Менаџер созвола" - }, - "adminPermissions": { - "message": "Админ дозволе" - }, "accessEventLogs": { "message": "Приступе извештаја догађаја" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Брише било коју колекцију" }, - "manageAssignedCollections": { - "message": "Управљање додељеним колекцијама" - }, "editAssignedCollections": { "message": "Уреди додељеним колекцијама" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Можете да доделите само колекције којима управљате." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Изаберите чланове" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Група" }, - "groupAccessAll": { - "message": "Ова група може приступити и изменити све ставке." - }, - "memberAccessAll": { - "message": "Овај члан може приступити и изменити све ставке." - }, "domainVerification": { "message": "Верификација домена" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Проверено" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index c7148218b3b..3211c0d1b7f 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Prijavi Se" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index 84db5a570ca..56b4506caea 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Logga in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Inloggning påbörjad" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Hanterare" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "Alla" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Behörighet" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Administratörsbehörigheter" - }, "accessEventLogs": { "message": "Åtkomst till händelseloggar" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Ta bort valfri samling" }, - "manageAssignedCollections": { - "message": "Hantera tilldelade samlingar" - }, "editAssignedCollections": { "message": "Redigera tilldelade samlingar" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Du kan endast tilldela samlingar som du hanterar." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Välj medlemmar" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grupp" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "Visa hemlighet" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index b34ccbb9013..9363c432ca2 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index 2f6fcd82645..aa854e62a2e 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "เข้าสู่ระบบ" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index 32dcc5f14e1..4607e0a037b 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Giriş yap" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Giriş başlatıldı" }, @@ -808,7 +811,7 @@ "message": "Beklenmedik bir hata oluştu." }, "expirationDateError": { - "message": "Lütfen gelecekte olan bir son kullanma tarihi seçin." + "message": "Lütfen gelecek tarihli bir son kullanma tarihi seçin." }, "emailAddress": { "message": "E-posta adresi" @@ -1366,19 +1369,19 @@ "message": "Verileri içe aktar" }, "onboardingImportDataDetailsPartOne": { - "message": "İçe aktarılacak veriniz yoksa bir tane oluşturun ", + "message": "İçe aktarılacak veriniz yoksa ", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsLink": { - "message": "yeni öge", + "message": "yeni bir kayıt", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsPartTwoNoOrgs": { - "message": " yerine.", + "message": " oluşturabilirsiniz.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead." }, "onboardingImportDataDetailsPartTwoWithOrgs": { - "message": " yerine. Yöneticiniz kuruluş üyeliğinizi onaylayana kadar beklemeniz gerekebilir.", + "message": " oluşturabilirsiniz. Yöneticiniz kuruluş üyeliğinizi onaylayana kadar beklemeniz gerekebilir.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "importError": { @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Atanmış koleksiyonlara erişebilir ve kayıt ekleyebilir" }, - "manager": { - "message": "Yetkili" - }, - "managerDesc": { - "message": "Atanmış koleksiyonlarda erişim oluşturabilir, silebilir ve yönetebilir" - }, "all": { "message": "Tümü" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "İzin" }, - "managerPermissions": { - "message": "Yetkili İzinleri" - }, - "adminPermissions": { - "message": "Yönetici İzinleri" - }, "accessEventLogs": { "message": "Olay günlüklerine erişme" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Tüm koleksiyonları silme" }, - "manageAssignedCollections": { - "message": "Atanmış koleksiyonları yönetme" - }, "editAssignedCollections": { "message": "Atanmış koleksiyonları düzenleme" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Mevcut ve gelecekteki tüm koleksiyonlara erişim izni verin." - }, - "accessAllCollectionsHelp": { - "message": "İşaretlenirse bu, diğer tüm koleksiyon izinlerinin yerini alacaktır." - }, "selectMembers": { "message": "Üyeleri seçin" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Grup" }, - "groupAccessAll": { - "message": "Bu grup tüm kayıtlara erişebilir ve kayıtları değiştirebilir." - }, - "memberAccessAll": { - "message": "Bu kullanıcı tüm kayıtlara erişebilir ve kayıtları değiştirebilir." - }, "domainVerification": { "message": "Alan adı doğrulama" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 0bbd19b8b80..1c3ff1e861d 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Увійти" }, + "verifyIdentity": { + "message": "Підтвердьте свою особу" + }, "logInInitiated": { "message": "Ініційовано вхід" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Доступ та додавання елементів до призначених збірок" }, - "manager": { - "message": "Менеджер" - }, - "managerDesc": { - "message": "Створення, видалення та керування доступом у призначених збірках" - }, "all": { "message": "Усі" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Дозвіл" }, - "managerPermissions": { - "message": "Дозволи менеджера" - }, - "adminPermissions": { - "message": "Дозволи адміністратора" - }, "accessEventLogs": { "message": "Доступ до журналів подій" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Видаляти будь-яку збірку" }, - "manageAssignedCollections": { - "message": "Керувати призначеними збірками" - }, "editAssignedCollections": { "message": "Редагувати призначені збірки" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "Ви можете призначити лише збірки, якими керуєте." }, - "accessAllCollectionsDesc": { - "message": "Надати доступ до всіх наявних і майбутніх збірок." - }, - "accessAllCollectionsHelp": { - "message": "Ця опція вилучить усі інші дозволи для збірок." - }, "selectMembers": { "message": "Вибрати учасників" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Група" }, - "groupAccessAll": { - "message": "Ця група має доступ і може редагувати всі елементи." - }, - "memberAccessAll": { - "message": "Цей учасник має доступ і може редагувати всі елементи." - }, "domainVerification": { "message": "Перевірка доменів" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Перевірений" + }, + "viewSecret": { + "message": "Переглянути секрет" + }, + "noClients": { + "message": "Немає клієнтів для перегляду" + }, + "providerBillingEmailHint": { + "message": "На цю адресу електронної пошти надсилатимуться всі рахунки, які стосуються цього провайдера", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index 47d69033e0d..eca409b21e6 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Đăng nhập" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "Access and add items to assigned collections" }, - "manager": { - "message": "Manager" - }, - "managerDesc": { - "message": "Create, delete, and manage access in assigned collections" - }, "all": { "message": "All" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "Permission" }, - "managerPermissions": { - "message": "Manager Permissions" - }, - "adminPermissions": { - "message": "Admin Permissions" - }, "accessEventLogs": { "message": "Access event logs" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "Delete any collection" }, - "manageAssignedCollections": { - "message": "Manage assigned collections" - }, "editAssignedCollections": { "message": "Edit assigned collections" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." - }, - "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." - }, "selectMembers": { "message": "Select members" }, @@ -6717,12 +6699,6 @@ "group": { "message": "Group" }, - "groupAccessAll": { - "message": "This group can access and modify all items." - }, - "memberAccessAll": { - "message": "This member can access and modify all items." - }, "domainVerification": { "message": "Domain verification" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 535c2abb7f3..5f5fd05e36f 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -588,7 +588,7 @@ "message": "已注销" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "您已注销您的账户。" }, "loginExpired": { "message": "您的登录会话已过期。" @@ -722,6 +722,9 @@ "logIn": { "message": "登录" }, + "verifyIdentity": { + "message": "验证您的身份" + }, "logInInitiated": { "message": "登录已发起" }, @@ -1054,10 +1057,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": "警告" @@ -2794,12 +2797,6 @@ "userDesc": { "message": "访问并添加项目到已分配的集合" }, - "manager": { - "message": "经理" - }, - "managerDesc": { - "message": "在已分配的集合中创建、删除和管理访问权限" - }, "all": { "message": "全部" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "权限" }, - "managerPermissions": { - "message": "经理权限" - }, - "adminPermissions": { - "message": "管理员权限" - }, "accessEventLogs": { "message": "访问事件日志" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "删除任意集合" }, - "manageAssignedCollections": { - "message": "管理已分配的集合" - }, "editAssignedCollections": { "message": "编辑已分配的集合" }, @@ -5602,13 +5590,13 @@ "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 或至少添加一个自定义环境。" }, "apiUrl": { "message": "API 服务器 URL" @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "您只能分配您管理的集合。" }, - "accessAllCollectionsDesc": { - "message": "授予对所有当前和未来的集合的访问权限。" - }, - "accessAllCollectionsHelp": { - "message": "如果选中,这将替换所有其他集合权限。" - }, "selectMembers": { "message": "选择成员" }, @@ -6717,12 +6699,6 @@ "group": { "message": "群组" }, - "groupAccessAll": { - "message": "此群组可以访问和修改所有项目。" - }, - "memberAccessAll": { - "message": "此成员可以访问和修改所有项目。" - }, "domainVerification": { "message": "域名验证" }, @@ -6901,7 +6877,7 @@ "message": "选择群组" }, "userPermissionOverrideHelperDesc": { - "message": "为成员设置的权限将替换为由该成员群组设置的权限。" + "message": "为成员设置的权限将替换掉该成员所属群组设置的权限。" }, "noMembersOrGroupsAdded": { "message": "未添加任何成员或群组" @@ -7501,7 +7477,7 @@ "message": "批准后,您将收到通知。" }, "troubleLoggingIn": { - "message": "登录遇到问题?" + "message": "登录遇到问题吗?" }, "loginApproved": { "message": "登录已批准" @@ -8347,12 +8323,22 @@ "message": "Bitcoin" }, "updatedTaxInformation": { - "message": "Updated tax information" + "message": "更新了税务信息" }, "unverified": { "message": "未验证" }, "verified": { "message": "已验证" + }, + "viewSecret": { + "message": "查看机密" + }, + "noClients": { + "message": "没有可列出的客户" + }, + "providerBillingEmailHint": { + "message": "此电子邮件地址将用于接收与此供应商相关的所有账单", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index e8413ed6fac..04a2e7f3ba5 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "登入" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "登入已發起" }, @@ -2794,12 +2797,6 @@ "userDesc": { "message": "存取和新增項目到已指派的集合中" }, - "manager": { - "message": "管理員" - }, - "managerDesc": { - "message": "在已指派的集合中創建、刪除以及管理存取權限" - }, "all": { "message": "全部" }, @@ -4576,12 +4573,6 @@ "permission": { "message": "權限" }, - "managerPermissions": { - "message": "經理權限" - }, - "adminPermissions": { - "message": "管理員權限" - }, "accessEventLogs": { "message": "存取事件紀錄" }, @@ -4606,9 +4597,6 @@ "deleteAnyCollection": { "message": "刪除任何集合" }, - "manageAssignedCollections": { - "message": "管理已指派的集合" - }, "editAssignedCollections": { "message": "編輯已指派的集合" }, @@ -6669,12 +6657,6 @@ "restrictedCollectionAssignmentDesc": { "message": "You can only assign collections you manage." }, - "accessAllCollectionsDesc": { - "message": "授予對所有目前和未來的集合的存取權限。" - }, - "accessAllCollectionsHelp": { - "message": "如果選中,這將取代所有其他集合權限。" - }, "selectMembers": { "message": "選擇成員" }, @@ -6717,12 +6699,6 @@ "group": { "message": "群組" }, - "groupAccessAll": { - "message": "此群組可存取及變更所有項目。" - }, - "memberAccessAll": { - "message": "此成員可存取及變更所有項目。" - }, "domainVerification": { "message": "網域驗證" }, @@ -8354,5 +8330,15 @@ }, "verified": { "message": "Verified" + }, + "viewSecret": { + "message": "View secret" + }, + "noClients": { + "message": "There are no clients to list" + }, + "providerBillingEmailHint": { + "message": "This email address will receive all invoices pertaining to this provider", + "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." } } From e3b425069c3b0f0e920ccf1b3123f752f989c736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Fri, 14 Jun 2024 11:36:26 +0200 Subject: [PATCH 04/29] [PM-8870] Fix argon2 in desktop (#9628) --- apps/desktop/src/main.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 738f053de73..80dbf40cb87 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -35,6 +35,7 @@ import { WindowMain } from "./main/window.main"; import { BiometricsService, BiometricsServiceAbstraction } from "./platform/main/biometric/index"; import { ClipboardMain } from "./platform/main/clipboard.main"; import { DesktopCredentialStorageListener } from "./platform/main/desktop-credential-storage-listener"; +import { MainCryptoFunctionService } from "./platform/main/main-crypto-function.service"; import { DesktopSettingsService } from "./platform/services/desktop-settings.service"; import { ElectronLogMainService } from "./platform/services/electron-log.main.service"; import { ElectronStorageService } from "./platform/services/electron-storage.service"; @@ -52,6 +53,7 @@ export class Main { environmentService: DefaultEnvironmentService; desktopCredentialStorageListener: DesktopCredentialStorageListener; desktopSettingsService: DesktopSettingsService; + mainCryptoFunctionService: MainCryptoFunctionService; migrationRunner: MigrationRunner; windowMain: WindowMain; @@ -111,6 +113,9 @@ export class Main { this.i18nService = new I18nMainService("en", "./locales/", globalStateProvider); + this.mainCryptoFunctionService = new MainCryptoFunctionService(); + this.mainCryptoFunctionService.init(); + const accountService = new AccountServiceImplementation( MessageSender.EMPTY, this.logService, From 94438d4138e20a97cc1939082628748f27bb7b67 Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Fri, 14 Jun 2024 08:24:50 -0500 Subject: [PATCH 05/29] [PM-8208] Fix: Product Navigation flash (#9587) * wait until a sync is complete to render the product switcher content * refactor unneeded observables into their own variable * do not show product switcher button until content is loaded * use `ReplaySubject` to ensure that `syncCompleted$` last value is always used --- .../product-switcher.component.html | 1 + .../product-switcher.component.ts | 9 ++- .../shared/product-switcher.service.spec.ts | 65 +++++++++++++++---- .../shared/product-switcher.service.ts | 58 ++++++++++++----- 4 files changed, 102 insertions(+), 31 deletions(-) diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.component.html b/apps/web/src/app/layouts/product-switcher/product-switcher.component.html index c9956f05e4a..f1942a02c20 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.component.html +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.component.html @@ -4,5 +4,6 @@ [bitMenuTriggerFor]="content?.menu" [buttonType]="buttonType" [attr.aria-label]="'switchProducts' | i18n" + *ngIf="products$ | async" > diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts b/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts index eff5f08702e..80155166394 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.component.ts @@ -1,6 +1,8 @@ import { AfterViewInit, ChangeDetectorRef, Component, Input } from "@angular/core"; import { IconButtonType } from "@bitwarden/components/src/icon-button/icon-button.component"; + +import { ProductSwitcherService } from "./shared/product-switcher.service"; @Component({ selector: "product-switcher", templateUrl: "./product-switcher.component.html", @@ -21,5 +23,10 @@ export class ProductSwitcherComponent implements AfterViewInit { this.changeDetector.detectChanges(); } - constructor(private changeDetector: ChangeDetectorRef) {} + constructor( + private changeDetector: ChangeDetectorRef, + private productSwitcherService: ProductSwitcherService, + ) {} + + protected readonly products$ = this.productSwitcherService.products$; } diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts index b98c2495e5a..07a41e7c94c 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts @@ -8,6 +8,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; +import { SyncService } from "@bitwarden/common/platform/sync"; import { ProductSwitcherService } from "./product-switcher.service"; @@ -17,8 +18,19 @@ describe("ProductSwitcherService", () => { let organizationService: MockProxy; let providerService: MockProxy; let activeRouteParams = convertToParamMap({ organizationId: "1234" }); + const getLastSync = jest.fn().mockResolvedValue(new Date("2024-05-14")); + + // The service is dependent on the SyncService, which is behind a `setTimeout` + // Most of the tests don't need to test this aspect so `advanceTimersByTime` + // is used to simulate the completion of the sync + function initiateService() { + service = TestBed.inject(ProductSwitcherService); + jest.advanceTimersByTime(201); + } beforeEach(() => { + jest.useFakeTimers(); + getLastSync.mockResolvedValue(new Date("2024-05-14")); router = mock(); organizationService = mock(); providerService = mock(); @@ -46,14 +58,40 @@ describe("ProductSwitcherService", () => { transform: (key: string) => key, }, }, + { + provide: SyncService, + useValue: { getLastSync }, + }, ], }); }); + afterEach(() => { + jest.useRealTimers(); + }); + + describe("SyncService", () => { + it("waits until sync is complete before emitting products", (done) => { + getLastSync.mockResolvedValue(null); + + initiateService(); + + // The subscription will only emit once the sync returns a value + service.products$.subscribe((products) => { + expect(products).toBeDefined(); + done(); + }); + + // Simulate sync completion & advance timers + getLastSync.mockResolvedValue(new Date("2024-05-15")); + jest.advanceTimersByTime(201); + }); + }); + describe("product separation", () => { describe("Password Manager", () => { it("is always included", async () => { - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -63,7 +101,7 @@ describe("ProductSwitcherService", () => { describe("Secret Manager", () => { it("is included in other when there are no organizations with SM", async () => { - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -75,7 +113,7 @@ describe("ProductSwitcherService", () => { { id: "1234", canAccessSecretsManager: true, enabled: true }, ] as Organization[]); - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -85,7 +123,7 @@ describe("ProductSwitcherService", () => { describe("Admin/Organizations", () => { it("includes Organizations in other when there are organizations", async () => { - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -96,7 +134,7 @@ describe("ProductSwitcherService", () => { it("includes Admin Console in bento when a user has access to it", async () => { organizationService.organizations$ = of([{ id: "1234", isOwner: true }] as Organization[]); - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -107,8 +145,7 @@ describe("ProductSwitcherService", () => { describe("Provider Portal", () => { it("is not included when there are no providers", async () => { - service = TestBed.inject(ProductSwitcherService); - + initiateService(); const products = await firstValueFrom(service.products$); expect(products.bento.find((p) => p.name === "Provider Portal")).toBeUndefined(); @@ -118,7 +155,7 @@ describe("ProductSwitcherService", () => { it("is included when there are providers", async () => { providerService.getAll.mockResolvedValue([{ id: "67899" }] as Provider[]); - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -129,7 +166,7 @@ describe("ProductSwitcherService", () => { describe("active product", () => { it("marks Password Manager as active", async () => { - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -141,7 +178,7 @@ describe("ProductSwitcherService", () => { it("marks Secret Manager as active", async () => { router.url = "/sm/"; - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -155,7 +192,7 @@ describe("ProductSwitcherService", () => { activeRouteParams = convertToParamMap({ organizationId: "1" }); router.url = "/organizations/"; - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -168,7 +205,7 @@ describe("ProductSwitcherService", () => { providerService.getAll.mockResolvedValue([{ id: "67899" }] as Provider[]); router.url = "/providers/"; - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -187,7 +224,7 @@ describe("ProductSwitcherService", () => { { id: "4243", canAccessSecretsManager: true, enabled: true, name: "Org 32" }, ] as Organization[]); - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); @@ -205,7 +242,7 @@ describe("ProductSwitcherService", () => { { id: "4243", isOwner: true, name: "My Org" }, ] as Organization[]); - service = TestBed.inject(ProductSwitcherService); + initiateService(); const products = await firstValueFrom(service.products$); diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts index 1a418ef3b00..434391cd50c 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts @@ -1,13 +1,6 @@ import { Injectable } from "@angular/core"; -import { - ActivatedRoute, - Event, - NavigationEnd, - NavigationStart, - ParamMap, - Router, -} from "@angular/router"; -import { combineLatest, concatMap, filter, map, Observable, startWith } from "rxjs"; +import { ActivatedRoute, NavigationEnd, NavigationStart, ParamMap, Router } from "@angular/router"; +import { combineLatest, concatMap, filter, map, Observable, ReplaySubject, startWith } from "rxjs"; import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe"; import { @@ -16,6 +9,7 @@ import { } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { SyncService } from "@bitwarden/common/platform/sync"; export type ProductSwitcherItem = { /** @@ -59,13 +53,38 @@ export type ProductSwitcherItem = { providedIn: "root", }) export class ProductSwitcherService { + /** + * Emits when the sync service has completed a sync + * + * Without waiting for a sync to be complete, in accurate product information + * can be displayed to the user for a brief moment until the sync is complete + * and all data is available. + */ + private syncCompleted$ = new ReplaySubject(1); + + /** + * Certain events should trigger an update to the `products$` observable but the values + * themselves are not needed. This observable is used to only trigger the update. + */ + private triggerProductUpdate$: Observable = combineLatest([ + this.syncCompleted$, + this.router.events.pipe( + // Product paths need to be updated when routes change, but the router event isn't actually needed + startWith(null), // Start with a null event to trigger the initial combineLatest + filter((e) => e instanceof NavigationEnd || e instanceof NavigationStart || e === null), + ), + ]).pipe(map(() => null)); + constructor( private organizationService: OrganizationService, private providerService: ProviderService, private route: ActivatedRoute, private router: Router, private i18n: I18nPipe, - ) {} + private syncService: SyncService, + ) { + this.pollUntilSynced(); + } products$: Observable<{ bento: ProductSwitcherItem[]; @@ -73,13 +92,9 @@ export class ProductSwitcherService { }> = combineLatest([ this.organizationService.organizations$, this.route.paramMap, - this.router.events.pipe( - // Product paths need to be updated when routes change, but the router event isn't actually needed - startWith(null), // Start with a null event to trigger the initial combineLatest - filter((e) => e instanceof NavigationEnd || e instanceof NavigationStart || e === null), - ), + this.triggerProductUpdate$, ]).pipe( - map(([orgs, ...rest]): [Organization[], ParamMap, Event | null] => { + map(([orgs, ...rest]): [Organization[], ParamMap, void] => { return [ // Sort orgs by name to match the order within the sidebar orgs.sort((a, b) => a.name.localeCompare(b.name)), @@ -186,4 +201,15 @@ export class ProductSwitcherService { }; }), ); + + /** Poll the `syncService` until a sync is completed */ + private pollUntilSynced() { + const interval = setInterval(async () => { + const lastSync = await this.syncService.getLastSync(); + if (lastSync !== null) { + clearInterval(interval); + this.syncCompleted$.next(); + } + }, 200); + } } From 9ef8404b7b72c85e7ef52e85437003b3e90c89e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 17:16:29 +0200 Subject: [PATCH 06/29] [deps] Tools: Update electron to v30 - abandoned (#8764) * [deps] Tools: Update electron to v30 * Bump version in electron-builder.json * Update to electron 30.1.0 --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel James Smith Co-authored-by: Hinton --- apps/desktop/electron-builder.json | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json index 39c62998a67..fd92d0007f3 100644 --- a/apps/desktop/electron-builder.json +++ b/apps/desktop/electron-builder.json @@ -24,7 +24,7 @@ "**/node_modules/argon2/package.json", "**/node_modules/argon2/lib/binding/napi-v3/argon2.node" ], - "electronVersion": "29.4.2", + "electronVersion": "30.1.0", "generateUpdatesFilesForAllChannels": true, "publish": { "provider": "generic", diff --git a/package-lock.json b/package-lock.json index 5c5d17352cb..ccf03377035 100644 --- a/package-lock.json +++ b/package-lock.json @@ -132,7 +132,7 @@ "copy-webpack-plugin": "12.0.2", "cross-env": "7.0.3", "css-loader": "6.10.0", - "electron": "29.4.2", + "electron": "30.1.0", "electron-builder": "24.13.3", "electron-log": "5.0.1", "electron-reload": "2.0.0-alpha.1", @@ -18563,9 +18563,9 @@ } }, "node_modules/electron": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/electron/-/electron-29.4.2.tgz", - "integrity": "sha512-XyIkuWQguwY8hGtLg0j5Q4Fqphdbh0ctBsKCSVzJ/R7Z2+2WN/oQ1M+zYwchmfiDgiuL3EKkrBrfPdxXYdMr+A==", + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-30.1.0.tgz", + "integrity": "sha512-9O8m7kinjwMH5Df0hpXbwUaqI6pk3aJm1sKQUkQGCF7NDbNkGhu2BXgqaicPU6oe26zQPc5vtwWnHmiKlh1hYA==", "dev": true, "hasInstallScript": true, "dependencies": { diff --git a/package.json b/package.json index 4d38e7eba55..0ceaa5fa303 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "copy-webpack-plugin": "12.0.2", "cross-env": "7.0.3", "css-loader": "6.10.0", - "electron": "29.4.2", + "electron": "30.1.0", "electron-builder": "24.13.3", "electron-log": "5.0.1", "electron-reload": "2.0.0-alpha.1", From eb96f7dbfb348036364b2d7d0903df5151d2a101 Mon Sep 17 00:00:00 2001 From: Cesar Gonzalez Date: Fri, 14 Jun 2024 10:26:41 -0500 Subject: [PATCH 07/29] [PM-8869] Fix broken autofill cache invalidation features on Safari (#9643) * [PM-8869] Autofill features broken on Safari * [PM-8869] Autofill features broken on Safari --- .../services/collect-autofill-content.service.ts | 5 +++-- apps/browser/src/autofill/utils/index.ts | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/browser/src/autofill/services/collect-autofill-content.service.ts b/apps/browser/src/autofill/services/collect-autofill-content.service.ts index 87470655786..39e75711561 100644 --- a/apps/browser/src/autofill/services/collect-autofill-content.service.ts +++ b/apps/browser/src/autofill/services/collect-autofill-content.service.ts @@ -21,6 +21,7 @@ import { nodeIsFormElement, nodeIsInputElement, sendExtensionMessage, + requestIdleCallbackPolyfill, } from "../utils"; import { AutofillOverlayContentService } from "./abstractions/autofill-overlay-content.service"; @@ -1057,7 +1058,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte } if (!this.mutationsQueue.length) { - globalThis.requestIdleCallback(this.processMutations, { timeout: 500 }); + requestIdleCallbackPolyfill(this.processMutations, { timeout: 500 }); } this.mutationsQueue.push(mutations); }; @@ -1194,7 +1195,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte continue; } - globalThis.requestIdleCallback( + requestIdleCallbackPolyfill( // We are setting this item to a -1 index because we do not know its position in the DOM. // This value should be updated with the next call to collect page details. () => void this.buildAutofillFieldItem(node as ElementWithOpId, -1), diff --git a/apps/browser/src/autofill/utils/index.ts b/apps/browser/src/autofill/utils/index.ts index cbb0a862e3c..e5d20cf9f59 100644 --- a/apps/browser/src/autofill/utils/index.ts +++ b/apps/browser/src/autofill/utils/index.ts @@ -1,6 +1,20 @@ import { AutofillPort } from "../enums/autofill-port.enums"; import { FillableFormFieldElement, FormFieldElement } from "../types"; +/** + * Polyfills the requestIdleCallback API with a setTimeout fallback. + * + * @param callback - The callback function to run when the browser is idle. + * @param options - The options to pass to the requestIdleCallback function. + */ +export function requestIdleCallbackPolyfill(callback: () => void, options?: Record) { + if ("requestIdleCallback" in globalThis) { + return globalThis.requestIdleCallback(() => callback(), options); + } + + return globalThis.setTimeout(() => callback(), 1); +} + /** * Generates a random string of characters that formatted as a custom element name. */ From 215bbc2f8efee1450230fe10494ac4893309fe43 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:40:56 -0400 Subject: [PATCH 08/29] Auth/PM-7324 - Registration with Email Verification - Registration Start Component Implementation (#9573) * PM-7324 - Register new registration start comp at signup route on web * PM-7324 - Add registerSendVerificationEmail logic in API service layer. * PM-7324 - Update registration start comp to actually send information to API and trigger email. * PM-7324 - progress on opt in for marketing emails redesign. * PM-7324 - Add feature flag and feature flag guard to sign up route. * PM-7324 - RegistrationEnvSelector - emit initial value * PM-7324 - Registration Start comp - wire up setReceiveMarketingEmailsByRegion logic. * PM-7324 - Registration start html - use proper link for email pref management. * PM-7324 - Translate text * PM-7324 - Design pass * PM-7324 - design pass v2 * PM-7324 - Update Tailwind config to add availability of anon layout to desktop and browser extension * PM-7324 - Desktop - AppRoutingModule - Add new signup route protected by the email verification feature flag. * PM-7324 - BrowserExtension - AppRoutingModule - Add signup route protected by feature flag * PM-7324 - Feature flag all register page navigations to redirect users to the new signup page. * PM-7324 - Update AnonLayoutWrapperComponent constructor logic to avoid passing undefined values into I18nService.t method * PM-7324 - Accept org invite web comp - adjust register url and qParams * PM-7324 - Add AnonLayoutWrapperData to desktop & browser since we don't need titleId. * PM-7324 - Revert anon layout wrapper comp changes as they were made separately and merged to main. * PM-7234 - Fix registration start component so the login route works for the browser extension. * PM-7324 - Registration start story now building again + fix storybook warning around BrowserAnimationsModule * PM-7324 - Registration Start - add missing tw-text-main to fix dark mode rendering. * PM-7324 - Update storybook docs * PM-7324 - Get stub of registration finish component so that the verify email has something to land on. * PM-7324 - Registration start - receive marketing materials should never be required. * PM-7324 - Add finish signup route + required translations to desktop & browser. * PM-7324 - AnonLayoutWrapperComponent - Resolve issues where navigating to a sibling anonymous route wouldn't update the AnonLayoutWrapperData. * PM-7324 - Remove unnecessary array * PM-7324 - Per PR feedback, improve setReceiveMarketingEmailsByRegion * PM-7324 - Per PR feedback, inject login routes via route data * PM-7324 - Document methods in account api service * PM-7324 - PR feedback - jsdoc tweaks --- apps/browser/src/_locales/en/messages.json | 21 +++++ .../src/auth/popup/home.component.html | 4 +- apps/browser/src/auth/popup/home.component.ts | 15 ++++ .../browser/src/auth/popup/login.component.ts | 3 + apps/browser/src/popup/app-routing.module.ts | 49 ++++++++++++ apps/browser/tailwind.config.js | 1 + apps/desktop/src/app/app-routing.module.ts | 50 ++++++++++++ .../src/auth/login/login.component.html | 2 +- .../desktop/src/auth/login/login.component.ts | 3 + apps/desktop/src/locales/en/messages.json | 21 +++++ apps/desktop/tailwind.config.js | 1 + .../accept-family-sponsorship.component.ts | 2 +- .../accept/accept-emergency.component.html | 2 +- .../accept/accept-emergency.component.ts | 4 +- .../src/app/auth/login/login.component.html | 2 +- .../web/src/app/auth/login/login.component.ts | 7 +- .../accept-organization.component.html | 2 +- .../accept-organization.component.ts | 26 ++++++- .../src/app/common/base.accept.component.ts | 17 ++++- apps/web/src/app/oss-routing.module.ts | 46 ++++++++++- .../src/app/tools/send/access.component.html | 2 +- .../src/app/tools/send/access.component.ts | 17 ++++- apps/web/src/locales/en/messages.json | 21 +++++ .../manage/accept-provider.component.html | 2 +- .../manage/accept-provider.component.ts | 4 +- .../src/auth/components/login.component.ts | 14 ++++ .../src/services/jslib-services.module.ts | 1 + .../anon-layout-wrapper.component.ts | 58 +++++++++++--- libs/auth/src/angular/index.ts | 1 + .../registration-env-selector.component.ts | 3 + .../registration-finish.component.html | 1 + .../registration-finish.component.ts | 15 ++++ ...egistration-start-secondary.component.html | 2 +- .../registration-start-secondary.component.ts | 25 +++++- .../registration-start.component.html | 52 +++++++++---- .../registration-start.component.ts | 76 ++++++++++++------- .../registration-start/registration-start.mdx | 25 +++--- .../registration-start.stories.ts | 9 ++- .../auth/abstractions/account-api.service.ts | 22 ++++++ ...egister-send-verification-email.request.ts | 7 ++ .../src/auth/services/account-api.service.ts | 35 +++++++++ libs/common/src/enums/feature-flag.enum.ts | 2 + 42 files changed, 584 insertions(+), 88 deletions(-) create mode 100644 libs/auth/src/angular/registration/registration-finish/registration-finish.component.html create mode 100644 libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts create mode 100644 libs/common/src/auth/models/request/registration/register-send-verification-email.request.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 39f95f09903..eb2815696e9 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -16,6 +16,12 @@ "createAccount": { "message": "Create account" }, + "setAStrongPassword": { + "message": "Set a strong password" + }, + "finishCreatingYourAccountBySettingAPassword": { + "message": "Finish creating your account by setting a password" + }, "login": { "message": "Log in" }, @@ -1780,6 +1786,21 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, + "receiveMarketingEmails": { + "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + }, + "unsubscribe": { + "message": "Unsubscribe" + }, + "atAnyTime": { + "message": "at any time." + }, + "byContinuingYouAgreeToThe": { + "message": "By continuing, you agree to the" + }, + "and": { + "message": "and" + }, "acceptPolicies": { "message": "By checking this box you agree to the following:" }, diff --git a/apps/browser/src/auth/popup/home.component.html b/apps/browser/src/auth/popup/home.component.html index 8e23d96c49d..35371948de9 100644 --- a/apps/browser/src/auth/popup/home.component.html +++ b/apps/browser/src/auth/popup/home.component.html @@ -30,7 +30,9 @@ diff --git a/apps/browser/src/auth/popup/home.component.ts b/apps/browser/src/auth/popup/home.component.ts index db83736be8a..e647dfd05b9 100644 --- a/apps/browser/src/auth/popup/home.component.ts +++ b/apps/browser/src/auth/popup/home.component.ts @@ -5,6 +5,8 @@ import { Subject, firstValueFrom, takeUntil } from "rxjs"; import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component"; import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -26,6 +28,9 @@ export class HomeComponent implements OnInit, OnDestroy { rememberEmail: [false], }); + // TODO: remove when email verification flag is removed + registerRoute = "/register"; + constructor( protected platformUtilsService: PlatformUtilsService, private formBuilder: FormBuilder, @@ -34,9 +39,19 @@ export class HomeComponent implements OnInit, OnDestroy { private environmentService: EnvironmentService, private loginEmailService: LoginEmailServiceAbstraction, private accountSwitcherService: AccountSwitcherService, + private configService: ConfigService, ) {} async ngOnInit(): Promise { + // TODO: remove when email verification flag is removed + const emailVerification = await this.configService.getFeatureFlag( + FeatureFlag.EmailVerification, + ); + + if (emailVerification) { + this.registerRoute = "/signup"; + } + const email = this.loginEmailService.getEmail(); const rememberEmail = this.loginEmailService.getRememberEmail(); diff --git a/apps/browser/src/auth/popup/login.component.ts b/apps/browser/src/auth/popup/login.component.ts index ff0ee8a392d..56a9aca68c7 100644 --- a/apps/browser/src/auth/popup/login.component.ts +++ b/apps/browser/src/auth/popup/login.component.ts @@ -13,6 +13,7 @@ import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstraction import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -51,6 +52,7 @@ export class LoginComponent extends BaseLoginComponent { loginEmailService: LoginEmailServiceAbstraction, ssoLoginService: SsoLoginServiceAbstraction, webAuthnLoginService: WebAuthnLoginServiceAbstraction, + configService: ConfigService, ) { super( devicesApiService, @@ -71,6 +73,7 @@ export class LoginComponent extends BaseLoginComponent { loginEmailService, ssoLoginService, webAuthnLoginService, + configService, ); super.onSuccessfulLogin = async () => { await syncService.fullSync(true); diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 1109ab73adf..51152ba0f71 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -8,6 +8,16 @@ import { tdeDecryptionRequiredGuard, unauthGuardFn, } from "@bitwarden/angular/auth/guards"; +import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard"; +import { + AnonLayoutWrapperComponent, + AnonLayoutWrapperData, + RegistrationFinishComponent, + RegistrationStartComponent, + RegistrationStartSecondaryComponent, + RegistrationStartSecondaryComponentData, +} from "@bitwarden/auth/angular"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { fido2AuthGuard } from "../auth/guards/fido2-auth.guard"; import { AccountSwitcherComponent } from "../auth/popup/account-switching/account-switcher.component"; @@ -343,6 +353,45 @@ const routes: Routes = [ canActivate: [AuthGuard], data: { state: "update-temp-password" }, }, + { + path: "", + component: AnonLayoutWrapperComponent, + children: [ + { + path: "signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { pageTitle: "createAccount" } satisfies AnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationStartComponent, + }, + { + path: "", + component: RegistrationStartSecondaryComponent, + outlet: "secondary", + data: { + loginRoute: "/home", + } satisfies RegistrationStartSecondaryComponentData, + }, + ], + }, + { + path: "finish-signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { + pageTitle: "setAStrongPassword", + pageSubtitle: "finishCreatingYourAccountBySettingAPassword", + } satisfies AnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationFinishComponent, + }, + ], + }, + ], + }, ...extensionRefreshSwap(AboutPageComponent, AboutPageV2Component, { path: "about", canActivate: [AuthGuard], diff --git a/apps/browser/tailwind.config.js b/apps/browser/tailwind.config.js index be5c9ce4d96..db1dd55694e 100644 --- a/apps/browser/tailwind.config.js +++ b/apps/browser/tailwind.config.js @@ -4,6 +4,7 @@ const config = require("../../libs/components/tailwind.config.base"); config.content = [ "./src/**/*.{html,ts}", "../../libs/components/src/**/*.{html,ts}", + "../../libs/auth/src/**/*.{html,ts}", "../../libs/angular/src/**/*.{html,ts}", ]; diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index bb8deb2339a..c7a66f510ca 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -6,7 +6,18 @@ import { lockGuard, redirectGuard, tdeDecryptionRequiredGuard, + unauthGuardFn, } from "@bitwarden/angular/auth/guards"; +import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard"; +import { + AnonLayoutWrapperComponent, + AnonLayoutWrapperData, + RegistrationFinishComponent, + RegistrationStartComponent, + RegistrationStartSecondaryComponent, + RegistrationStartSecondaryComponentData, +} from "@bitwarden/auth/angular"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { AccessibilityCookieComponent } from "../auth/accessibility-cookie.component"; import { maxAccountsGuardFn } from "../auth/guards/max-accounts.guard"; @@ -82,6 +93,45 @@ const routes: Routes = [ canActivate: [AuthGuard], data: { titleId: "removeMasterPassword" }, }, + { + path: "", + component: AnonLayoutWrapperComponent, + children: [ + { + path: "signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { pageTitle: "createAccount" } satisfies AnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationStartComponent, + }, + { + path: "", + component: RegistrationStartSecondaryComponent, + outlet: "secondary", + data: { + loginRoute: "/login", + } satisfies RegistrationStartSecondaryComponentData, + }, + ], + }, + { + path: "finish-signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { + pageTitle: "setAStrongPassword", + pageSubtitle: "finishCreatingYourAccountBySettingAPassword", + } satisfies AnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationFinishComponent, + }, + ], + }, + ], + }, ]; @NgModule({ diff --git a/apps/desktop/src/auth/login/login.component.html b/apps/desktop/src/auth/login/login.component.html index eef0580d4e1..d9983220745 100644 --- a/apps/desktop/src/auth/login/login.component.html +++ b/apps/desktop/src/auth/login/login.component.html @@ -48,7 +48,7 @@

{{ "newAroundHere" | i18n }}

-
diff --git a/apps/desktop/src/auth/login/login.component.ts b/apps/desktop/src/auth/login/login.component.ts index a810a29a26c..fd57e9015b1 100644 --- a/apps/desktop/src/auth/login/login.component.ts +++ b/apps/desktop/src/auth/login/login.component.ts @@ -15,6 +15,7 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/ import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -71,6 +72,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy { loginEmailService: LoginEmailServiceAbstraction, ssoLoginService: SsoLoginServiceAbstraction, webAuthnLoginService: WebAuthnLoginServiceAbstraction, + configService: ConfigService, ) { super( devicesApiService, @@ -91,6 +93,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy { loginEmailService, ssoLoginService, webAuthnLoginService, + configService, ); super.onSuccessfulLogin = () => { return syncService.fullSync(true); diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 7846457294e..0c5f7244f01 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -499,6 +499,12 @@ "createAccount": { "message": "Create account" }, + "setAStrongPassword": { + "message": "Set a strong password" + }, + "finishCreatingYourAccountBySettingAPassword": { + "message": "Finish creating your account by setting a password" + }, "logIn": { "message": "Log in" }, @@ -1659,6 +1665,21 @@ "masterPasswordPolicyRequirementsNotMet": { "message": "Your new master password does not meet the policy requirements." }, + "receiveMarketingEmails": { + "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + }, + "unsubscribe": { + "message": "Unsubscribe" + }, + "atAnyTime": { + "message": "at any time." + }, + "byContinuingYouAgreeToThe": { + "message": "By continuing, you agree to the" + }, + "and": { + "message": "and" + }, "acceptPolicies": { "message": "By checking this box you agree to the following:" }, diff --git a/apps/desktop/tailwind.config.js b/apps/desktop/tailwind.config.js index be5c9ce4d96..db1dd55694e 100644 --- a/apps/desktop/tailwind.config.js +++ b/apps/desktop/tailwind.config.js @@ -4,6 +4,7 @@ const config = require("../../libs/components/tailwind.config.base"); config.content = [ "./src/**/*.{html,ts}", "../../libs/components/src/**/*.{html,ts}", + "../../libs/auth/src/**/*.{html,ts}", "../../libs/angular/src/**/*.{html,ts}", ]; diff --git a/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts b/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts index 46a75c37360..e5733e262f6 100644 --- a/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts +++ b/apps/web/src/app/admin-console/organizations/sponsorships/accept-family-sponsorship.component.ts @@ -27,7 +27,7 @@ export class AcceptFamilySponsorshipComponent extends BaseAcceptComponent { } else { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/register"], { queryParams: { email: qParams.email } }); + this.router.navigate([this.registerRoute], { queryParams: { email: qParams.email } }); } } } diff --git a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html index 3e1db406316..11491bd5560 100644 --- a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html +++ b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html @@ -29,7 +29,7 @@ diff --git a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts index 5a92815c91f..378726b8407 100644 --- a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts +++ b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts @@ -2,6 +2,7 @@ import { Component } from "@angular/core"; import { ActivatedRoute, Params, Router } from "@angular/router"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -28,9 +29,10 @@ export class AcceptEmergencyComponent extends BaseAcceptComponent { i18nService: I18nService, route: ActivatedRoute, authService: AuthService, + configService: ConfigService, private emergencyAccessService: EmergencyAccessService, ) { - super(router, platformUtilsService, i18nService, route, authService); + super(router, platformUtilsService, i18nService, route, authService, configService); } async authedHandler(qParams: Params): Promise { diff --git a/apps/web/src/app/auth/login/login.component.html b/apps/web/src/app/auth/login/login.component.html index eb2a9a88aa1..9f2939ed452 100644 --- a/apps/web/src/app/auth/login/login.component.html +++ b/apps/web/src/app/auth/login/login.component.html @@ -56,7 +56,7 @@

{{ "newAroundHere" | i18n }} - {{ "createAccount" | i18n }} + {{ "createAccount" | i18n }}

diff --git a/apps/web/src/app/auth/login/login.component.ts b/apps/web/src/app/auth/login/login.component.ts index 1f174b7397a..fb86fbc45dd 100644 --- a/apps/web/src/app/auth/login/login.component.ts +++ b/apps/web/src/app/auth/login/login.component.ts @@ -20,6 +20,7 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/ import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -67,6 +68,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { loginEmailService: LoginEmailServiceAbstraction, ssoLoginService: SsoLoginServiceAbstraction, webAuthnLoginService: WebAuthnLoginServiceAbstraction, + configService: ConfigService, ) { super( devicesApiService, @@ -87,6 +89,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { loginEmailService, ssoLoginService, webAuthnLoginService, + configService, ); this.onSuccessfulLoginNavigate = this.goAfterLogIn; this.showPasswordless = flagEnabled("showPasswordless"); @@ -165,11 +168,11 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { const email = this.formGroup.value.email; if (email) { - await this.router.navigate(["/register"], { queryParams: { email: email } }); + await this.router.navigate([this.registerRoute], { queryParams: { email: email } }); return; } - await this.router.navigate(["/register"]); + await this.router.navigate([this.registerRoute]); } protected override async handleMigrateEncryptionKey(result: AuthResult): Promise { diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.component.html b/apps/web/src/app/auth/organization-invite/accept-organization.component.html index f9dd3da5ed9..6e88d03ffae 100644 --- a/apps/web/src/app/auth/organization-invite/accept-organization.component.html +++ b/apps/web/src/app/auth/organization-invite/accept-organization.component.html @@ -32,7 +32,7 @@ {{ "logIn" | i18n }} diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.component.ts b/apps/web/src/app/auth/organization-invite/accept-organization.component.ts index fa5507b216f..7326c5a5b56 100644 --- a/apps/web/src/app/auth/organization-invite/accept-organization.component.ts +++ b/apps/web/src/app/auth/organization-invite/accept-organization.component.ts @@ -2,6 +2,7 @@ import { Component } from "@angular/core"; import { ActivatedRoute, Params, Router } from "@angular/router"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -23,9 +24,10 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent { i18nService: I18nService, route: ActivatedRoute, authService: AuthService, + configService: ConfigService, private acceptOrganizationInviteService: AcceptOrganizationInviteService, ) { - super(router, platformUtilsService, i18nService, route, authService); + super(router, platformUtilsService, i18nService, route, authService, configService); } async authedHandler(qParams: Params): Promise { @@ -86,8 +88,26 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent { // if SSO is disabled OR if sso is enabled but the SSO login required policy is not enabled // then send user to create account - await this.router.navigate(["/register"], { - queryParams: { email: invite.email, fromOrgInvite: true }, + + // TODO: update logic when email verification flag is removed + let queryParams: Params; + if (this.registerRoute === "/register") { + queryParams = { + fromOrgInvite: "true", + email: invite.email, + }; + } else if (this.registerRoute === "/signup") { + // We have to override the base component route b/c it is correct for other components + // that extend the base accept comp. We don't need users to complete email verification + // if they are coming directly from an emailed org invite. + this.registerRoute = "/finish-signup"; + queryParams = { + email: invite.email, + }; + } + + await this.router.navigate([this.registerRoute], { + queryParams: queryParams, }); return; } diff --git a/apps/web/src/app/common/base.accept.component.ts b/apps/web/src/app/common/base.accept.component.ts index 7c35751aea6..32ba232b088 100644 --- a/apps/web/src/app/common/base.accept.component.ts +++ b/apps/web/src/app/common/base.accept.component.ts @@ -5,6 +5,8 @@ import { first, switchMap, takeUntil } from "rxjs/operators"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -19,6 +21,9 @@ export abstract class BaseAcceptComponent implements OnInit { protected failedShortMessage = "inviteAcceptFailedShort"; protected failedMessage = "inviteAcceptFailed"; + // TODO: remove when email verification flag is removed + registerRoute = "/register"; + private destroy$ = new Subject(); constructor( @@ -27,12 +32,22 @@ export abstract class BaseAcceptComponent implements OnInit { protected i18nService: I18nService, protected route: ActivatedRoute, protected authService: AuthService, + private configService: ConfigService, ) {} abstract authedHandler(qParams: Params): Promise; abstract unauthedHandler(qParams: Params): Promise; - ngOnInit() { + async ngOnInit() { + // TODO: remove when email verification flag is removed + const emailVerification = await this.configService.getFeatureFlag( + FeatureFlag.EmailVerification, + ); + + if (emailVerification) { + this.registerRoute = "/signup"; + } + this.route.queryParams .pipe( first(), diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 46930f92c94..36cd563bc6a 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -9,7 +9,16 @@ import { UnauthGuard, unauthGuardFn, } from "@bitwarden/angular/auth/guards"; -import { AnonLayoutWrapperComponent, AnonLayoutWrapperData } from "@bitwarden/auth/angular"; +import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard"; +import { + AnonLayoutWrapperComponent, + AnonLayoutWrapperData, + RegistrationFinishComponent, + RegistrationStartComponent, + RegistrationStartSecondaryComponent, + RegistrationStartSecondaryComponentData, +} from "@bitwarden/auth/angular"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { flagEnabled, Flags } from "../utils/flags"; @@ -175,6 +184,41 @@ const routes: Routes = [ path: "", component: AnonLayoutWrapperComponent, children: [ + { + path: "signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { pageTitle: "createAccount", titleId: "createAccount" } satisfies DataProperties & + AnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationStartComponent, + }, + { + path: "", + component: RegistrationStartSecondaryComponent, + outlet: "secondary", + data: { + loginRoute: "/login", + } satisfies RegistrationStartSecondaryComponentData, + }, + ], + }, + { + path: "finish-signup", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], + data: { + pageTitle: "setAStrongPassword", + pageSubtitle: "finishCreatingYourAccountBySettingAPassword", + titleId: "setAStrongPassword", + } satisfies DataProperties & AnonLayoutWrapperData, + children: [ + { + path: "", + component: RegistrationFinishComponent, + }, + ], + }, { path: "sso", canActivate: [unauthGuardFn()], diff --git a/apps/web/src/app/tools/send/access.component.html b/apps/web/src/app/tools/send/access.component.html index 6fef7d361d5..60f172c481c 100644 --- a/apps/web/src/app/tools/send/access.component.html +++ b/apps/web/src/app/tools/send/access.component.html @@ -75,7 +75,7 @@ >Bitwarden Send {{ "sendAccessTaglineOr" | i18n }} - {{ + {{ "sendAccessTaglineSignUp" | i18n }} {{ "sendAccessTaglineTryToday" | i18n }} diff --git a/apps/web/src/app/tools/send/access.component.ts b/apps/web/src/app/tools/send/access.component.ts index d307f4bdf97..9915bf52043 100644 --- a/apps/web/src/app/tools/send/access.component.ts +++ b/apps/web/src/app/tools/send/access.component.ts @@ -2,7 +2,9 @@ import { Component, OnInit } from "@angular/core"; import { FormBuilder } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -54,6 +56,9 @@ export class AccessComponent implements OnInit { protected formGroup = this.formBuilder.group({}); + // TODO: remove when email verification flag is removed + registerRoute = "/register"; + private id: string; private key: string; @@ -64,6 +69,7 @@ export class AccessComponent implements OnInit { private sendApiService: SendApiService, private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, + private configService: ConfigService, protected formBuilder: FormBuilder, ) {} @@ -81,7 +87,16 @@ export class AccessComponent implements OnInit { return this.send.creatorIdentifier; } - ngOnInit() { + async ngOnInit() { + // TODO: remove when email verification flag is removed + const emailVerification = await this.configService.getFeatureFlag( + FeatureFlag.EmailVerification, + ); + + if (emailVerification) { + this.registerRoute = "/signup"; + } + // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe this.route.params.subscribe(async (params) => { this.id = params.sendId; diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 964cfe75362..344e70b50a9 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -713,6 +713,12 @@ "createAccount": { "message": "Create account" }, + "setAStrongPassword": { + "message": "Set a strong password" + }, + "finishCreatingYourAccountBySettingAPassword": { + "message": "Finish creating your account by setting a password" + }, "newAroundHere": { "message": "New around here?" }, @@ -3724,6 +3730,21 @@ "nothingSelected": { "message": "You have not selected anything." }, + "receiveMarketingEmails": { + "message": "Get emails from Bitwarden for announcements, advice, and research opportunities." + }, + "unsubscribe": { + "message": "Unsubscribe" + }, + "atAnyTime": { + "message": "at any time." + }, + "byContinuingYouAgreeToThe": { + "message": "By continuing, you agree to the" + }, + "and": { + "message": "and" + }, "acceptPolicies": { "message": "By checking this box you agree to the following:" }, diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.html index d8e6f030418..a3323b6c2c1 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.html @@ -31,7 +31,7 @@ diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.ts index 2c6742611d7..f2396139525 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/accept-provider.component.ts @@ -4,6 +4,7 @@ import { ActivatedRoute, Params, Router } from "@angular/router"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ProviderUserAcceptRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-user-accept.request"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { BaseAcceptComponent } from "@bitwarden/web-vault/app/common/base.accept.component"; @@ -26,8 +27,9 @@ export class AcceptProviderComponent extends BaseAcceptComponent { authService: AuthService, private apiService: ApiService, platformUtilService: PlatformUtilsService, + configService: ConfigService, ) { - super(router, platformUtilService, i18nService, route, authService); + super(router, platformUtilService, i18nService, route, authService, configService); } async authedHandler(qParams: Params) { diff --git a/libs/angular/src/auth/components/login.component.ts b/libs/angular/src/auth/components/login.component.ts index cfef72c435c..69c11e50568 100644 --- a/libs/angular/src/auth/components/login.component.ts +++ b/libs/angular/src/auth/components/login.component.ts @@ -14,7 +14,9 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/ import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -56,6 +58,8 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, protected twoFactorRoute = "2fa"; protected successRoute = "vault"; + // TODO: remove when email verification flag is removed + protected registerRoute = "/register"; protected forcePasswordResetRoute = "update-temp-password"; protected destroy$ = new Subject(); @@ -83,11 +87,21 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, protected loginEmailService: LoginEmailServiceAbstraction, protected ssoLoginService: SsoLoginServiceAbstraction, protected webAuthnLoginService: WebAuthnLoginServiceAbstraction, + protected configService: ConfigService, ) { super(environmentService, i18nService, platformUtilsService); } async ngOnInit() { + // TODO: remove when email verification flag is removed + const emailVerification = await this.configService.getFeatureFlag( + FeatureFlag.EmailVerification, + ); + + if (emailVerification) { + this.registerRoute = "/signup"; + } + this.route?.queryParams.pipe(takeUntil(this.destroy$)).subscribe((params) => { if (!params) { return; diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 78b2e81672e..e364b290715 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -486,6 +486,7 @@ const safeProviders: SafeProvider[] = [ UserVerificationServiceAbstraction, LogService, InternalAccountService, + EnvironmentService, ], }), safeProvider({ diff --git a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts index e4472c368f6..30ef5c1f767 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout-wrapper.component.ts @@ -1,5 +1,6 @@ -import { Component } from "@angular/core"; -import { ActivatedRoute, RouterModule } from "@angular/router"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute, Data, NavigationEnd, Router, RouterModule } from "@angular/router"; +import { Subject, filter, switchMap, takeUntil, tap } from "rxjs"; import { AnonLayoutComponent } from "@bitwarden/auth/angular"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -17,31 +18,64 @@ export interface AnonLayoutWrapperData { templateUrl: "anon-layout-wrapper.component.html", imports: [AnonLayoutComponent, RouterModule], }) -export class AnonLayoutWrapperComponent { +export class AnonLayoutWrapperComponent implements OnInit, OnDestroy { + private destroy$ = new Subject(); + protected pageTitle: string; protected pageSubtitle: string; protected pageIcon: Icon; protected showReadonlyHostname: boolean; constructor( + private router: Router, private route: ActivatedRoute, private i18nService: I18nService, - ) { - const routeData = this.route.snapshot.firstChild?.data; + ) {} - if (!routeData) { + ngOnInit(): void { + // Set the initial page data on load + this.setAnonLayoutWrapperData(this.route.snapshot.firstChild?.data); + + // Listen for page changes and update the page data appropriately + this.router.events + .pipe( + filter((event) => event instanceof NavigationEnd), + // reset page data on page changes + tap(() => this.resetPageData()), + switchMap(() => this.route.firstChild?.data || null), + takeUntil(this.destroy$), + ) + .subscribe((firstChildRouteData: Data | null) => { + this.setAnonLayoutWrapperData(firstChildRouteData); + }); + } + + private setAnonLayoutWrapperData(firstChildRouteData: Data | null) { + if (!firstChildRouteData) { return; } - if (routeData["pageTitle"] !== undefined) { - this.pageTitle = this.i18nService.t(routeData["pageTitle"]); + if (firstChildRouteData["pageTitle"] !== undefined) { + this.pageTitle = this.i18nService.t(firstChildRouteData["pageTitle"]); } - if (routeData["pageSubtitle"] !== undefined) { - this.pageSubtitle = this.i18nService.t(routeData["pageSubtitle"]); + if (firstChildRouteData["pageSubtitle"] !== undefined) { + this.pageSubtitle = this.i18nService.t(firstChildRouteData["pageSubtitle"]); } - this.pageIcon = routeData["pageIcon"]; - this.showReadonlyHostname = routeData["showReadonlyHostname"]; + this.pageIcon = firstChildRouteData["pageIcon"]; + this.showReadonlyHostname = firstChildRouteData["showReadonlyHostname"]; + } + + private resetPageData() { + this.pageTitle = null; + this.pageSubtitle = null; + this.pageIcon = null; + this.showReadonlyHostname = null; + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); } } diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index eb8fd0416a9..9c660413cd3 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -17,5 +17,6 @@ export * from "./user-verification/user-verification-form-input.component"; // registration export * from "./registration/registration-start/registration-start.component"; +export * from "./registration/registration-finish/registration-finish.component"; export * from "./registration/registration-start/registration-start-secondary.component"; export * from "./registration/registration-env-selector/registration-env-selector.component"; diff --git a/libs/auth/src/angular/registration/registration-env-selector/registration-env-selector.component.ts b/libs/auth/src/angular/registration/registration-env-selector/registration-env-selector.component.ts index fe41f0a3ac7..268fb1cc996 100644 --- a/libs/auth/src/angular/registration/registration-env-selector/registration-env-selector.component.ts +++ b/libs/auth/src/angular/registration/registration-env-selector/registration-env-selector.component.ts @@ -93,6 +93,9 @@ export class RegistrationEnvSelectorComponent implements OnInit, OnDestroy { // Save this off so we can reset the value to the previously selected region // if the self hosted settings are closed without saving. this.selectedRegionFromEnv = selectedRegionFromEnv; + + // Emit the initial value + this.selectedRegionChange.emit(selectedRegionFromEnv); }), takeUntil(this.destroy$), ) diff --git a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.html b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.html new file mode 100644 index 00000000000..2bf6b6fc59d --- /dev/null +++ b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.html @@ -0,0 +1 @@ +

This component will be built in the next phase of email verification work.

diff --git a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts new file mode 100644 index 00000000000..fb344c6e1ad --- /dev/null +++ b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts @@ -0,0 +1,15 @@ +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; +import { RouterModule } from "@angular/router"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; + +@Component({ + standalone: true, + selector: "auth-registration-finish", + templateUrl: "./registration-finish.component.html", + imports: [CommonModule, JslibModule, RouterModule], +}) +export class RegistrationFinishComponent { + constructor() {} +} diff --git a/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.html b/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.html index 00bed13d3a5..c878724106b 100644 --- a/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.html +++ b/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.html @@ -1,3 +1,3 @@ {{ "alreadyHaveAccount" | i18n }}
{{ "logIn" | i18n }}{{ "alreadyHaveAccount" | i18n }} {{ "logIn" | i18n }} diff --git a/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.ts b/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.ts index d28214bd575..1c2883beb08 100644 --- a/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.ts +++ b/libs/auth/src/angular/registration/registration-start/registration-start-secondary.component.ts @@ -1,15 +1,32 @@ import { CommonModule } from "@angular/common"; -import { Component } from "@angular/core"; -import { RouterModule } from "@angular/router"; +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute, RouterModule } from "@angular/router"; +import { firstValueFrom } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +/** + * RegistrationStartSecondaryComponentData + * @loginRoute: string - The client specific route to the login page - configured at the app-routing.module level. + */ +export interface RegistrationStartSecondaryComponentData { + loginRoute: string; +} + @Component({ standalone: true, selector: "auth-registration-start-secondary", templateUrl: "./registration-start-secondary.component.html", imports: [CommonModule, JslibModule, RouterModule], }) -export class RegistrationStartSecondaryComponent { - constructor() {} +export class RegistrationStartSecondaryComponent implements OnInit { + loginRoute: string; + + constructor(private activatedRoute: ActivatedRoute) {} + + async ngOnInit() { + const routeData = await firstValueFrom(this.activatedRoute.data); + + this.loginRoute = routeData["loginRoute"]; + } } diff --git a/libs/auth/src/angular/registration/registration-start/registration-start.component.html b/libs/auth/src/angular/registration/registration-start/registration-start.component.html index 8da2eb76b55..4bb926093a5 100644 --- a/libs/auth/src/angular/registration/registration-start/registration-start.component.html +++ b/libs/auth/src/angular/registration/registration-start/registration-start.component.html @@ -23,38 +23,60 @@ - - {{ "acceptPolicies" | i18n }} + + {{ "receiveMarketingEmails" | i18n }} {{ "termsOfService" | i18n }}, - {{ "privacyPolicy" | i18n }}{{ "unsubscribe" | i18n }} + {{ "atAnyTime" | i18n }} - +

+ {{ "byContinuingYouAgreeToThe" | i18n }} + {{ "termsOfService" | i18n }} + {{ "and" | i18n }} + {{ "privacyPolicy" | i18n }} +

+ +
diff --git a/libs/auth/src/angular/registration/registration-start/registration-start.component.ts b/libs/auth/src/angular/registration/registration-start/registration-start.component.ts index 3674efdbf0f..4a45589ee1b 100644 --- a/libs/auth/src/angular/registration/registration-start/registration-start.component.ts +++ b/libs/auth/src/angular/registration/registration-start/registration-start.component.ts @@ -1,17 +1,12 @@ import { CommonModule } from "@angular/common"; import { Component, EventEmitter, OnDestroy, OnInit, Output } from "@angular/core"; -import { - AbstractControl, - FormBuilder, - FormControl, - ReactiveFormsModule, - ValidatorFn, - Validators, -} from "@angular/forms"; -import { ActivatedRoute } from "@angular/router"; +import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; +import { ActivatedRoute, Router } from "@angular/router"; import { Subject, takeUntil } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service"; +import { RegisterSendVerificationEmailRequest } from "@bitwarden/common/auth/models/request/registration/register-send-verification-email.request"; import { RegionConfig, Region } from "@bitwarden/common/platform/abstractions/environment.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { @@ -31,6 +26,12 @@ export enum RegistrationStartState { CHECK_EMAIL = "CheckEmail", } +const DEFAULT_MARKETING_EMAILS_PREF_BY_REGION: Record = { + [Region.US]: true, + [Region.EU]: false, + [Region.SelfHosted]: false, +}; + @Component({ standalone: true, selector: "auth-registration-start", @@ -60,20 +61,19 @@ export class RegistrationStartComponent implements OnInit, OnDestroy { formGroup = this.formBuilder.group({ email: ["", [Validators.required, Validators.email]], name: [""], - acceptPolicies: [false, [this.acceptPoliciesValidator()]], - selectedRegion: [null], + receiveMarketingEmails: [false], }); - get email(): FormControl { - return this.formGroup.get("email") as FormControl; + get email() { + return this.formGroup.controls.email; } - get name(): FormControl { - return this.formGroup.get("name") as FormControl; + get name() { + return this.formGroup.controls.name; } - get acceptPolicies(): FormControl { - return this.formGroup.get("acceptPolicies") as FormControl; + get receiveMarketingEmails() { + return this.formGroup.controls.receiveMarketingEmails; } emailReadonly: boolean = false; @@ -86,8 +86,9 @@ export class RegistrationStartComponent implements OnInit, OnDestroy { private formBuilder: FormBuilder, private route: ActivatedRoute, private platformUtilsService: PlatformUtilsService, + private accountApiService: AccountApiService, + private router: Router, ) { - // TODO: this needs to update if user selects self hosted this.isSelfHost = platformUtilsService.isSelfHost(); } @@ -107,6 +108,18 @@ export class RegistrationStartComponent implements OnInit, OnDestroy { }); } + setReceiveMarketingEmailsByRegion(region: RegionConfig | Region.SelfHosted) { + let defaultValue; + if (region === Region.SelfHosted) { + defaultValue = DEFAULT_MARKETING_EMAILS_PREF_BY_REGION[region]; + } else { + const regionKey = (region as RegionConfig).key; + defaultValue = DEFAULT_MARKETING_EMAILS_PREF_BY_REGION[regionKey]; + } + + this.receiveMarketingEmails.setValue(defaultValue); + } + submit = async () => { const valid = this.validateForm(); @@ -114,14 +127,31 @@ export class RegistrationStartComponent implements OnInit, OnDestroy { return; } - // TODO: Implement registration logic + const request: RegisterSendVerificationEmailRequest = new RegisterSendVerificationEmailRequest( + this.email.value, + this.name.value, + this.receiveMarketingEmails.value, + ); + const result = await this.accountApiService.registerSendVerificationEmail(request); + + if (typeof result === "string") { + // we received a token, so the env doesn't support email verification + // send the user directly to the finish registration page with the token as a query param + await this.router.navigate(["/finish-signup"], { queryParams: { token: result } }); + } + + // Result is null, so email verification is required this.state = RegistrationStartState.CHECK_EMAIL; this.registrationStartStateChange.emit(this.state); }; handleSelectedRegionChange(region: RegionConfig | Region.SelfHosted | null) { this.isSelfHost = region === Region.SelfHosted; + + if (region !== null) { + this.setReceiveMarketingEmailsByRegion(region); + } } private validateForm(): boolean { @@ -139,14 +169,6 @@ export class RegistrationStartComponent implements OnInit, OnDestroy { this.registrationStartStateChange.emit(this.state); } - private acceptPoliciesValidator(): ValidatorFn { - return (control: AbstractControl) => { - const ctrlValue = control.value; - - return !ctrlValue && !this.isSelfHost ? { required: true } : null; - }; - } - ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); diff --git a/libs/auth/src/angular/registration/registration-start/registration-start.mdx b/libs/auth/src/angular/registration/registration-start/registration-start.mdx index 1da14d24e4d..a9654de22fc 100644 --- a/libs/auth/src/angular/registration/registration-start/registration-start.mdx +++ b/libs/auth/src/angular/registration/registration-start/registration-start.mdx @@ -8,8 +8,9 @@ import * as stories from "./registration-start.stories"; The Auth-owned RegistrationStartComponent is to be used for the first step in the new email verification stage gated registration process. It collects the environment (required), the user's -email address (required) and optionally their name. On cloud environments, it requires acceptance of -the terms of service and the privacy policy; the checkbox is hidden on self hosted environments. +email address (required) and optionally their name. On cloud environments, it offers a checkbox for +the user to choose to receive marketing emails or not with the default value changing based on the +environment (e.g., true for US, false for EU). ## Web Examples @@ -36,8 +37,10 @@ field will be set to readonly. `emailReadonly` is primarily for the organization Behavior to note: - The self hosted option is present in the environment selector. -- If you go from non-self hosted to self hosted, the terms of service and privacy policy checkbox - will disappear. +- If you go from non-self hosted to self hosted, the receive marketing emails checkbox will + disappear. +- If you change regions, the receive marketing emails checkbox default value will change based on + the region. ### US Region @@ -49,8 +52,8 @@ Behavior to note: ### Self Hosted -Note the fact that the terms of service and privacy policy checkbox is not present when the -environment is self hosted. +Note the fact that the receive marketing emails checkbox is not present when the environment is self +hosted. @@ -59,8 +62,10 @@ environment is self hosted. Behavior to note: - The self hosted option is present in the environment selector. -- If you go from non-self hosted to self hosted, the terms of service and privacy policy checkbox - will disappear. +- If you go from non-self hosted to self hosted, the receive marketing emails checkbox will + disappear. +- If you change regions, the receive marketing emails checkbox default value will change based on + the region. ### US Region @@ -72,7 +77,7 @@ Behavior to note: ### Self Hosted -Note the fact that the terms of service and privacy policy checkbox is not present when the -environment is self hosted. +Note the fact that the receive marketing emails checkbox is not present when the environment is self +hosted. diff --git a/libs/auth/src/angular/registration/registration-start/registration-start.stories.ts b/libs/auth/src/angular/registration/registration-start/registration-start.stories.ts index 50d1f15182e..d0670dd10c4 100644 --- a/libs/auth/src/angular/registration/registration-start/registration-start.stories.ts +++ b/libs/auth/src/angular/registration/registration-start/registration-start.stories.ts @@ -6,6 +6,7 @@ import { RouterTestingModule } from "@angular/router/testing"; import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; import { of } from "rxjs"; +import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service"; import { ClientType } from "@bitwarden/common/enums"; import { Environment, @@ -53,7 +54,6 @@ const decorators = (options: { LinkModule, TypographyModule, AsyncActionsModule, - BrowserAnimationsModule, ], providers: [ { @@ -64,6 +64,7 @@ const decorators = (options: { }), applicationConfig({ providers: [ + importProvidersFrom(BrowserAnimationsModule), importProvidersFrom(PreloadedEnglishI18nModule), { provide: EnvironmentService, @@ -91,6 +92,12 @@ const decorators = (options: { showToast: (options: ToastOptions) => {}, } as Partial, }, + { + provide: AccountApiService, + useValue: { + registerSendVerificationEmail: () => Promise.resolve(null), + } as Partial, + }, ], }), ]; diff --git a/libs/common/src/auth/abstractions/account-api.service.ts b/libs/common/src/auth/abstractions/account-api.service.ts index a897dcd5ce2..cc63589400a 100644 --- a/libs/common/src/auth/abstractions/account-api.service.ts +++ b/libs/common/src/auth/abstractions/account-api.service.ts @@ -1,5 +1,27 @@ +import { RegisterSendVerificationEmailRequest } from "../models/request/registration/register-send-verification-email.request"; import { Verification } from "../types/verification"; export abstract class AccountApiService { + /** + * Deletes an account that has confirmed the operation is authorized + * + * @param verification - authorizes the account deletion operation. + * @returns A promise that resolves when the account is + * successfully deleted. + */ abstract deleteAccount(verification: Verification): Promise; + + /** + * Sends a verification email as part of the registration process. + * + * @param request - The request object containing + * information needed to send the verification email, such as the user's email address. + * @returns A promise that resolves to a string tokencontaining the user's encrypted + * information which must be submitted to complete registration or `null` if + * email verification is enabled (users must get the token by clicking a + * link in the email that will be sent to them). + */ + abstract registerSendVerificationEmail( + request: RegisterSendVerificationEmailRequest, + ): Promise; } diff --git a/libs/common/src/auth/models/request/registration/register-send-verification-email.request.ts b/libs/common/src/auth/models/request/registration/register-send-verification-email.request.ts new file mode 100644 index 00000000000..c568d1fe290 --- /dev/null +++ b/libs/common/src/auth/models/request/registration/register-send-verification-email.request.ts @@ -0,0 +1,7 @@ +export class RegisterSendVerificationEmailRequest { + constructor( + public email: string, + public name: string, + public receiveMarketingEmails: boolean, + ) {} +} diff --git a/libs/common/src/auth/services/account-api.service.ts b/libs/common/src/auth/services/account-api.service.ts index 409babe618f..0573786d2ad 100644 --- a/libs/common/src/auth/services/account-api.service.ts +++ b/libs/common/src/auth/services/account-api.service.ts @@ -1,8 +1,13 @@ +import { firstValueFrom } from "rxjs"; + import { ApiService } from "../../abstractions/api.service"; +import { ErrorResponse } from "../../models/response/error.response"; +import { EnvironmentService } from "../../platform/abstractions/environment.service"; import { LogService } from "../../platform/abstractions/log.service"; import { AccountApiService } from "../abstractions/account-api.service"; import { InternalAccountService } from "../abstractions/account.service"; import { UserVerificationService } from "../abstractions/user-verification/user-verification.service.abstraction"; +import { RegisterSendVerificationEmailRequest } from "../models/request/registration/register-send-verification-email.request"; import { Verification } from "../types/verification"; export class AccountApiServiceImplementation implements AccountApiService { @@ -11,6 +16,7 @@ export class AccountApiServiceImplementation implements AccountApiService { private userVerificationService: UserVerificationService, private logService: LogService, private accountService: InternalAccountService, + private environmentService: EnvironmentService, ) {} async deleteAccount(verification: Verification): Promise { @@ -23,4 +29,33 @@ export class AccountApiServiceImplementation implements AccountApiService { throw e; } } + + async registerSendVerificationEmail( + request: RegisterSendVerificationEmailRequest, + ): Promise { + const env = await firstValueFrom(this.environmentService.environment$); + + try { + const response = await this.apiService.send( + "POST", + "/accounts/register/send-verification-email", + request, + false, + true, + env.getIdentityUrl(), + ); + + return response; + } catch (e: unknown) { + if (e instanceof ErrorResponse) { + if (e.statusCode === 204) { + // No content is a success response. + return null; + } + } + + this.logService.error(e); + throw e; + } + } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index f3bea6964ec..ec93dfcb2a0 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -17,6 +17,7 @@ export enum FeatureFlag { RestrictProviderAccess = "restrict-provider-access", UseTreeWalkerApiForPageDetailsCollection = "use-tree-walker-api-for-page-details-collection", BulkDeviceApproval = "bulk-device-approval", + EmailVerification = "email-verification", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -44,6 +45,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.RestrictProviderAccess]: FALSE, [FeatureFlag.UseTreeWalkerApiForPageDetailsCollection]: FALSE, [FeatureFlag.BulkDeviceApproval]: FALSE, + [FeatureFlag.EmailVerification]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; From af53df09ac2aff6e47dd2d4f4939ee8e0c8e3dfd Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:27:49 -0400 Subject: [PATCH 09/29] [AC-1944] Add provider billing history component (#9520) * Add provider-billing-history.component * Implement provider client invoice export --- apps/web/src/locales/en/messages.json | 10 +++ .../providers/providers-layout.component.html | 1 + .../providers/providers-routing.module.ts | 8 +++ .../providers/providers.module.ts | 2 + .../provider-billing-history.component.html | 9 +++ .../provider-billing-history.component.ts | 48 ++++++++++++++ .../src/app/billing/providers/index.ts | 1 + libs/angular/src/billing/components/index.ts | 1 + .../invoices/invoices.component.html | 66 +++++++++++++++++++ .../components/invoices/invoices.component.ts | 49 ++++++++++++++ libs/angular/src/jslib.module.ts | 9 +++ .../billilng-api.service.abstraction.ts | 5 ++ .../models/response/invoices.response.ts | 34 ++++++++++ .../billing/services/billing-api.service.ts | 24 +++++++ libs/common/src/services/api.service.ts | 3 + 15 files changed, 270 insertions(+) create mode 100644 bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.html create mode 100644 bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts create mode 100644 libs/angular/src/billing/components/invoices/invoices.component.html create mode 100644 libs/angular/src/billing/components/invoices/invoices.component.ts create mode 100644 libs/common/src/billing/models/response/invoices.response.ts diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 344e70b50a9..5b9e7c9c829 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8361,5 +8361,15 @@ "providerBillingEmailHint": { "message": "This email address will receive all invoices pertaining to this provider", "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." + }, + "date": { + "message": "Date" + }, + "exportClientReport": { + "message": "Export client report" + }, + "invoiceNumberHeader": { + "message": "Invoice number", + "description": "A table header for an invoice's number" } } 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 ffcfcd0ad81..7ee6a067d42 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 @@ -34,6 +34,7 @@ > + + +

{{ "invoices" | i18n }}

+ +
diff --git a/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts new file mode 100644 index 00000000000..24ca4cf36dd --- /dev/null +++ b/bitwarden_license/bit-web/src/app/billing/providers/billing-history/provider-billing-history.component.ts @@ -0,0 +1,48 @@ +import { DatePipe } from "@angular/common"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { map, Subject, takeUntil } from "rxjs"; + +import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions"; +import { InvoiceResponse } from "@bitwarden/common/billing/models/response/invoices.response"; + +@Component({ + templateUrl: "./provider-billing-history.component.html", +}) +export class ProviderBillingHistoryComponent implements OnInit, OnDestroy { + private providerId: string; + + private destroy$ = new Subject(); + + constructor( + private activatedRoute: ActivatedRoute, + private billingApiService: BillingApiServiceAbstraction, + private datePipe: DatePipe, + ) {} + + getClientInvoiceReport = (invoiceId: string) => + this.billingApiService.getProviderClientInvoiceReport(this.providerId, invoiceId); + + getClientInvoiceReportName = (invoice: InvoiceResponse) => { + const date = this.datePipe.transform(invoice.date, "yyyyMMdd"); + return `bitwarden_provider_${date}_${invoice.number}`; + }; + + getInvoices = async () => await this.billingApiService.getProviderInvoices(this.providerId); + + ngOnInit() { + this.activatedRoute.params + .pipe( + map(({ providerId }) => { + this.providerId = providerId; + }), + takeUntil(this.destroy$), + ) + .subscribe(); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } +} diff --git a/bitwarden_license/bit-web/src/app/billing/providers/index.ts b/bitwarden_license/bit-web/src/app/billing/providers/index.ts index 71af56f7b0d..c16862888dc 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/index.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/index.ts @@ -1,3 +1,4 @@ +export * from "./billing-history/provider-billing-history.component"; export * from "./clients"; export * from "./guards/has-consolidated-billing.guard"; export * from "./payment-method/provider-select-payment-method-dialog.component"; diff --git a/libs/angular/src/billing/components/index.ts b/libs/angular/src/billing/components/index.ts index 748a005df83..5db97c869de 100644 --- a/libs/angular/src/billing/components/index.ts +++ b/libs/angular/src/billing/components/index.ts @@ -1,4 +1,5 @@ export * from "./add-account-credit-dialog/add-account-credit-dialog.component"; +export * from "./invoices/invoices.component"; export * from "./manage-tax-information/manage-tax-information.component"; export * from "./select-payment-method/select-payment-method.component"; export * from "./verify-bank-account/verify-bank-account.component"; diff --git a/libs/angular/src/billing/components/invoices/invoices.component.html b/libs/angular/src/billing/components/invoices/invoices.component.html new file mode 100644 index 00000000000..c3823005546 --- /dev/null +++ b/libs/angular/src/billing/components/invoices/invoices.component.html @@ -0,0 +1,66 @@ + + + {{ "loading" | i18n }} + + + + + {{ "date" | i18n }} + {{ "invoiceNumberHeader" | i18n }} + {{ "total" | i18n }} + {{ "status" | i18n }} + + + + + {{ invoice.date | date: "mediumDate" }} + + + {{ invoice.number }} + + + {{ invoice.total | currency: "$" }} + {{ invoice.status | titlecase }} + + + + + + {{ "viewInvoice" | i18n }} + + + + + + + diff --git a/libs/angular/src/billing/components/invoices/invoices.component.ts b/libs/angular/src/billing/components/invoices/invoices.component.ts new file mode 100644 index 00000000000..3a16bff58ee --- /dev/null +++ b/libs/angular/src/billing/components/invoices/invoices.component.ts @@ -0,0 +1,49 @@ +import { Component, Input, OnInit } from "@angular/core"; + +import { + InvoiceResponse, + InvoicesResponse, +} from "@bitwarden/common/billing/models/response/invoices.response"; +import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; + +@Component({ + selector: "app-invoices", + templateUrl: "./invoices.component.html", +}) +export class InvoicesComponent implements OnInit { + @Input() startWith?: InvoicesResponse; + @Input() getInvoices?: () => Promise; + @Input() getClientInvoiceReport?: (invoiceId: string) => Promise; + @Input() getClientInvoiceReportName?: (invoiceResponse: InvoiceResponse) => string; + + protected invoices: InvoiceResponse[] = []; + protected loading = true; + + constructor(private fileDownloadService: FileDownloadService) {} + + runExport = async (invoiceId: string): Promise => { + const blobData = await this.getClientInvoiceReport(invoiceId); + let fileName = "report.csv"; + if (this.getClientInvoiceReportName) { + const invoice = this.invoices.find((invoice) => invoice.id === invoiceId); + fileName = this.getClientInvoiceReportName(invoice); + } + this.fileDownloadService.download({ + fileName, + blobData, + blobOptions: { + type: "text/csv", + }, + }); + }; + + async ngOnInit(): Promise { + if (this.startWith) { + this.invoices = this.startWith.invoices; + } else if (this.getInvoices) { + const response = await this.getInvoices(); + this.invoices = response.invoices; + } + this.loading = false; + } +} diff --git a/libs/angular/src/jslib.module.ts b/libs/angular/src/jslib.module.ts index ccb7446d863..59d50ee389a 100644 --- a/libs/angular/src/jslib.module.ts +++ b/libs/angular/src/jslib.module.ts @@ -4,6 +4,7 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { AddAccountCreditDialogComponent, + InvoicesComponent, ManageTaxInformationComponent, SelectPaymentMethodComponent, VerifyBankAccountComponent, @@ -15,8 +16,11 @@ import { CheckboxModule, DialogModule, FormFieldModule, + IconButtonModule, + MenuModule, RadioButtonModule, SelectModule, + TableModule, ToastModule, TypographyModule, } from "@bitwarden/components"; @@ -66,6 +70,9 @@ import { IconComponent } from "./vault/components/icon.component"; CheckboxModule, DialogModule, TypographyModule, + TableModule, + MenuModule, + IconButtonModule, ], declarations: [ A11yInvalidDirective, @@ -96,6 +103,7 @@ import { IconComponent } from "./vault/components/icon.component"; IfFeatureDirective, FingerprintPipe, AddAccountCreditDialogComponent, + InvoicesComponent, ManageTaxInformationComponent, SelectPaymentMethodComponent, VerifyBankAccountComponent, @@ -130,6 +138,7 @@ import { IconComponent } from "./vault/components/icon.component"; IfFeatureDirective, FingerprintPipe, AddAccountCreditDialogComponent, + InvoicesComponent, ManageTaxInformationComponent, SelectPaymentMethodComponent, VerifyBankAccountComponent, diff --git a/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts b/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts index 117b318768e..de3d6dd1e98 100644 --- a/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts +++ b/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts @@ -2,6 +2,7 @@ import { PaymentMethodType } from "@bitwarden/common/billing/enums"; import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request"; import { TokenizedPaymentMethodRequest } from "@bitwarden/common/billing/models/request/tokenized-payment-method.request"; import { VerifyBankAccountRequest } from "@bitwarden/common/billing/models/request/verify-bank-account.request"; +import { InvoicesResponse } from "@bitwarden/common/billing/models/response/invoices.response"; import { PaymentInformationResponse } from "@bitwarden/common/billing/models/response/payment-information.response"; import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request"; @@ -41,6 +42,10 @@ export abstract class BillingApiServiceAbstraction { getPlans: () => Promise>; + getProviderClientInvoiceReport: (providerId: string, invoiceId: string) => Promise; + + getProviderInvoices: (providerId: string) => Promise; + getProviderPaymentInformation: (providerId: string) => Promise; getProviderSubscription: (providerId: string) => Promise; diff --git a/libs/common/src/billing/models/response/invoices.response.ts b/libs/common/src/billing/models/response/invoices.response.ts new file mode 100644 index 00000000000..73170ff5c96 --- /dev/null +++ b/libs/common/src/billing/models/response/invoices.response.ts @@ -0,0 +1,34 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +export class InvoicesResponse extends BaseResponse { + invoices: InvoiceResponse[] = []; + + constructor(response: any) { + super(response); + const invoices = this.getResponseProperty("Invoices"); + if (invoices && invoices.length) { + this.invoices = invoices.map((t: any) => new InvoiceResponse(t)); + } + } +} + +export class InvoiceResponse extends BaseResponse { + id: string; + date: string; + number: string; + total: number; + status: string; + url: string; + pdfUrl: string; + + constructor(response: any) { + super(response); + this.id = this.getResponseProperty("Id"); + this.date = this.getResponseProperty("Date"); + this.number = this.getResponseProperty("Number"); + this.total = this.getResponseProperty("Total"); + this.status = this.getResponseProperty("Status"); + this.url = this.getResponseProperty("Url"); + this.pdfUrl = this.getResponseProperty("PdfUrl"); + } +} diff --git a/libs/common/src/billing/services/billing-api.service.ts b/libs/common/src/billing/services/billing-api.service.ts index 13e5205bdd9..333c9ab0119 100644 --- a/libs/common/src/billing/services/billing-api.service.ts +++ b/libs/common/src/billing/services/billing-api.service.ts @@ -1,3 +1,5 @@ +import { InvoicesResponse } from "@bitwarden/common/billing/models/response/invoices.response"; + import { ApiService } from "../../abstractions/api.service"; import { BillingApiServiceAbstraction } from "../../billing/abstractions"; import { PaymentMethodType } from "../../billing/enums"; @@ -106,6 +108,28 @@ export class BillingApiService implements BillingApiServiceAbstraction { return new ListResponse(r, PlanResponse); } + async getProviderClientInvoiceReport(providerId: string, invoiceId: string): Promise { + const response = await this.apiService.send( + "GET", + "/providers/" + providerId + "/billing/invoices/" + invoiceId, + null, + true, + true, + ); + return response as string; + } + + async getProviderInvoices(providerId: string): Promise { + const response = await this.apiService.send( + "GET", + "/providers/" + providerId + "/billing/invoices", + null, + true, + true, + ); + return new InvoicesResponse(response); + } + async getProviderPaymentInformation(providerId: string): Promise { const response = await this.apiService.send( "GET", diff --git a/libs/common/src/services/api.service.ts b/libs/common/src/services/api.service.ts index 61cfcb25837..40ff5e7bef3 100644 --- a/libs/common/src/services/api.service.ts +++ b/libs/common/src/services/api.service.ts @@ -1883,9 +1883,12 @@ export class ApiService implements ApiServiceAbstraction { const responseType = response.headers.get("content-type"); const responseIsJson = responseType != null && responseType.indexOf("application/json") !== -1; + const responseIsCsv = responseType != null && responseType.indexOf("text/csv") !== -1; if (hasResponse && response.status === 200 && responseIsJson) { const responseJson = await response.json(); return responseJson; + } else if (hasResponse && response.status === 200 && responseIsCsv) { + return await response.text(); } else if (response.status !== 200) { const error = await this.handleError(response, false, authed); return Promise.reject(error); From 977712873bd0b12d63a4d54c2749bba1f04fb0c9 Mon Sep 17 00:00:00 2001 From: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:58:44 -0400 Subject: [PATCH 10/29] Bumped client version(s) (#9655) --- apps/browser/package.json | 2 +- apps/browser/src/manifest.json | 2 +- apps/browser/src/manifest.v3.json | 2 +- package-lock.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/browser/package.json b/apps/browser/package.json index a295a0f5bfe..9cef485e48e 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2024.6.0", + "version": "2024.6.1", "scripts": { "build": "cross-env MANIFEST_VERSION=3 webpack", "build:mv2": "webpack", diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index 7f6e4957158..da9c1574efd 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.6.0", + "version": "2024.6.1", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index ed35ab3021f..8f3ee73e395 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -3,7 +3,7 @@ "minimum_chrome_version": "102.0", "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.6.0", + "version": "2024.6.1", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/package-lock.json b/package-lock.json index ccf03377035..1c48fa7c8ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -197,7 +197,7 @@ }, "apps/browser": { "name": "@bitwarden/browser", - "version": "2024.6.0" + "version": "2024.6.1" }, "apps/cli": { "name": "@bitwarden/cli", From 87c1f9c2af4f644b6a9eb6d66fc2a5d8ae9ce8e1 Mon Sep 17 00:00:00 2001 From: Robyn MacCallum Date: Fri, 14 Jun 2024 12:59:47 -0400 Subject: [PATCH 11/29] Update build-browser.yml (#9654) --- .github/workflows/build-browser.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index f924c5c98ea..14bc578bef1 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -186,17 +186,10 @@ jobs: # path: browser-source/apps/browser/dist/dist-opera-mv3.zip # if-no-files-found: error - - name: Upload Chrome artifact + - name: Upload Chrome MV3 artifact uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: dist-chrome-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-chrome.zip - if-no-files-found: error - - - name: Upload Chrome MV3 artifact (DO NOT USE FOR PROD) - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - with: - name: DO-NOT-USE-FOR-PROD-dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip + name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip path: browser-source/apps/browser/dist/dist-chrome-mv3.zip if-no-files-found: error From 6e7239e05eb3687c5a9da5256411258a69ed3a9d Mon Sep 17 00:00:00 2001 From: Cesar Gonzalez Date: Fri, 14 Jun 2024 12:08:13 -0500 Subject: [PATCH 12/29] [PM-8885] Hardcode Fallback to TreeWalker Strategy for PageCollection details (#9652) --- .../services/collect-autofill-content.service.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/browser/src/autofill/services/collect-autofill-content.service.ts b/apps/browser/src/autofill/services/collect-autofill-content.service.ts index 39e75711561..4205590973b 100644 --- a/apps/browser/src/autofill/services/collect-autofill-content.service.ts +++ b/apps/browser/src/autofill/services/collect-autofill-content.service.ts @@ -20,7 +20,7 @@ import { elementIsTextAreaElement, nodeIsFormElement, nodeIsInputElement, - sendExtensionMessage, + // sendExtensionMessage, requestIdleCallbackPolyfill, } from "../utils"; @@ -57,7 +57,7 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte "image", "file", ]); - private useTreeWalkerStrategyFlagSet = false; + private useTreeWalkerStrategyFlagSet = true; constructor( domElementVisibilityService: DomElementVisibilityService, @@ -72,10 +72,10 @@ class CollectAutofillContentService implements CollectAutofillContentServiceInte } this.formFieldQueryString = `${inputQuery}, textarea:not([data-bwignore]), select:not([data-bwignore]), span[data-bwautofill]`; - void sendExtensionMessage("getUseTreeWalkerApiForPageDetailsCollectionFeatureFlag").then( - (useTreeWalkerStrategyFlag) => - (this.useTreeWalkerStrategyFlagSet = !!useTreeWalkerStrategyFlag?.result), - ); + // void sendExtensionMessage("getUseTreeWalkerApiForPageDetailsCollectionFeatureFlag").then( + // (useTreeWalkerStrategyFlag) => + // (this.useTreeWalkerStrategyFlagSet = !!useTreeWalkerStrategyFlag?.result), + // ); } /** From 44b59714589b261bc3ffdc35560caeaae64a2db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Fri, 14 Jun 2024 13:19:51 -0400 Subject: [PATCH 13/29] [PM-8857] fix passphrase missing number (#9634) --- .../tools/generator/passphrase/passphrase-generator-strategy.ts | 2 +- .../core/src/strategies/passphrase-generator-strategy.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/common/src/tools/generator/passphrase/passphrase-generator-strategy.ts b/libs/common/src/tools/generator/passphrase/passphrase-generator-strategy.ts index 3ed6a1219ce..bf381845704 100644 --- a/libs/common/src/tools/generator/passphrase/passphrase-generator-strategy.ts +++ b/libs/common/src/tools/generator/passphrase/passphrase-generator-strategy.ts @@ -51,7 +51,7 @@ export class PassphraseGeneratorStrategy // select which word gets the number, if any let luckyNumber = -1; if (o.includeNumber) { - luckyNumber = await this.randomizer.uniform(0, o.numWords); + luckyNumber = await this.randomizer.uniform(0, o.numWords - 1); } // generate the passphrase diff --git a/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts b/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts index 023c9f531d9..7fdadaf8e24 100644 --- a/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts +++ b/libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts @@ -47,7 +47,7 @@ export class PassphraseGeneratorStrategy // select which word gets the number, if any let luckyNumber = -1; if (o.includeNumber) { - luckyNumber = await this.randomizer.uniform(0, o.numWords); + luckyNumber = await this.randomizer.uniform(0, o.numWords - 1); } // generate the passphrase From a95ca524c688f08f2c0a5f0c3a19c5bb76c28619 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:49:27 -0400 Subject: [PATCH 14/29] PM-8866 - Fix Recover delete component submit missing form validation. (#9658) --- apps/web/src/app/auth/recover-delete.component.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/web/src/app/auth/recover-delete.component.ts b/apps/web/src/app/auth/recover-delete.component.ts index 6688c1582ec..96afd910598 100644 --- a/apps/web/src/app/auth/recover-delete.component.ts +++ b/apps/web/src/app/auth/recover-delete.component.ts @@ -13,9 +13,13 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl }) export class RecoverDeleteComponent { protected recoverDeleteForm = new FormGroup({ - email: new FormControl(null, [Validators.required]), + email: new FormControl("", [Validators.required]), }); + get email() { + return this.recoverDeleteForm.controls.email; + } + constructor( private router: Router, private apiService: ApiService, @@ -24,8 +28,12 @@ export class RecoverDeleteComponent { ) {} submit = async () => { + if (this.recoverDeleteForm.invalid) { + return; + } + const request = new DeleteRecoverRequest(); - request.email = this.recoverDeleteForm.value.email.trim().toLowerCase(); + request.email = this.email.value.trim().toLowerCase(); await this.apiService.postAccountRecoverDelete(request); this.platformUtilsService.showToast( "success", From 966737c2e2a006e2be50697fc5f0f3b13478b01a Mon Sep 17 00:00:00 2001 From: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:58:33 -0400 Subject: [PATCH 15/29] Bumped client version(s) (#9661) --- apps/desktop/package.json | 2 +- apps/desktop/src/package-lock.json | 4 ++-- apps/desktop/src/package.json | 2 +- package-lock.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 4bb0a94961e..bbb4540b35c 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.6.1", + "version": "2024.6.2", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index c29ec0a9eea..69265370328 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.6.1", + "version": "2024.6.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.6.1", + "version": "2024.6.2", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-native": "file:../desktop_native", diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index 04406eea1d4..18d7d9332d4 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2024.6.1", + "version": "2024.6.2", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/package-lock.json b/package-lock.json index 1c48fa7c8ea..57accf47c4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -237,7 +237,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2024.6.1", + "version": "2024.6.2", "hasInstallScript": true, "license": "GPL-3.0" }, From dda17885f9f9102fd8c79ca0a5357cb9f4a6b54d Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:06:56 -0400 Subject: [PATCH 16/29] PM-8867 - RecoverDelete comp - fix missing page title (#9660) --- apps/web/src/app/oss-routing.module.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 36cd563bc6a..7dafb9ab6a1 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -304,14 +304,14 @@ const routes: Routes = [ { path: "recover-delete", canActivate: [unauthGuardFn()], + data: { + pageTitle: "deleteAccount", + titleId: "deleteAccount", + } satisfies DataProperties & AnonLayoutWrapperData, children: [ { path: "", component: RecoverDeleteComponent, - data: { - pageTitle: "deleteAccount", - titleId: "deleteAccount", - } satisfies DataProperties & AnonLayoutWrapperData, }, { path: "", From 90cdd9343b21204d62d0dca6e0e2b31a8a2ec840 Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:16:13 -0500 Subject: [PATCH 17/29] [Fix] Storybook: product navigation errors (#9664) * fix product switcher stories by adding sync service mock * remove redundant await --- .../navigation-switcher/navigation-switcher.stories.ts | 8 ++++++++ .../layouts/product-switcher/product-switcher.stories.ts | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts index 241c927f39e..48a45deba89 100644 --- a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts @@ -9,6 +9,7 @@ import { ProviderService } from "@bitwarden/common/admin-console/abstractions/pr import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { SyncService } from "@bitwarden/common/platform/sync"; import { LayoutComponent, NavigationModule } from "@bitwarden/components"; import { I18nMockService } from "@bitwarden/components/src/utils/i18n-mock.service"; @@ -45,6 +46,12 @@ class MockProviderService implements Partial { } } +class MockSyncService implements Partial { + async getLastSync() { + return Promise.resolve(new Date()); + } +} + @Component({ selector: "story-layout", template: ``, @@ -80,6 +87,7 @@ export default { providers: [ { provide: OrganizationService, useClass: MockOrganizationService }, { provide: ProviderService, useClass: MockProviderService }, + { provide: MockSyncService, useClass: MockSyncService }, ProductSwitcherService, { provide: I18nPipe, diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts index a653e11ae03..b9d1d394920 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts @@ -9,6 +9,7 @@ import { ProviderService } from "@bitwarden/common/admin-console/abstractions/pr import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { SyncService } from "@bitwarden/common/platform/sync"; import { IconButtonModule, LinkModule, MenuModule } from "@bitwarden/components"; import { I18nMockService } from "@bitwarden/components/src/utils/i18n-mock.service"; @@ -45,6 +46,12 @@ class MockProviderService implements Partial { } } +class MockSyncService implements Partial { + async getLastSync() { + return Promise.resolve(new Date()); + } +} + @Component({ selector: "story-layout", template: ``, @@ -75,6 +82,7 @@ export default { MockOrganizationService, { provide: ProviderService, useClass: MockProviderService }, MockProviderService, + { provide: SyncService, useClass: MockSyncService }, ProductSwitcherService, { provide: I18nService, From aba64b989ba31689f714f99539d5a603d6bcaf41 Mon Sep 17 00:00:00 2001 From: Robyn MacCallum Date: Fri, 14 Jun 2024 15:20:17 -0400 Subject: [PATCH 18/29] Update release-browser.yml (#9667) --- .github/workflows/release-browser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-browser.yml b/.github/workflows/release-browser.yml index c260f19581c..68c33ca358e 100644 --- a/.github/workflows/release-browser.yml +++ b/.github/workflows/release-browser.yml @@ -132,7 +132,7 @@ jobs: PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }} run: | mv browser-source.zip browser-source-$PACKAGE_VERSION.zip - mv dist-chrome.zip dist-chrome-$PACKAGE_VERSION.zip + mv dist-chrome-mv3.zip dist-chrome-$PACKAGE_VERSION.zip mv dist-opera.zip dist-opera-$PACKAGE_VERSION.zip mv dist-firefox.zip dist-firefox-$PACKAGE_VERSION.zip mv dist-edge.zip dist-edge-$PACKAGE_VERSION.zip From e521d702ba61f6f8f3b7ec03efd6e2d2af64cc8d Mon Sep 17 00:00:00 2001 From: Bitwarden DevOps <106330231+bitwarden-devops-bot@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:41:36 -0400 Subject: [PATCH 19/29] Bumped client version(s) (#9668) --- apps/desktop/package.json | 2 +- apps/desktop/src/package-lock.json | 4 ++-- apps/desktop/src/package.json | 2 +- package-lock.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index bbb4540b35c..c78b72cf268 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.6.2", + "version": "2024.6.3", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index 69265370328..560e812de8b 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.6.2", + "version": "2024.6.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.6.2", + "version": "2024.6.3", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-native": "file:../desktop_native", diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index 18d7d9332d4..d836b894986 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2024.6.2", + "version": "2024.6.3", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/package-lock.json b/package-lock.json index 57accf47c4c..fe43d36aaf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -237,7 +237,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2024.6.2", + "version": "2024.6.3", "hasInstallScript": true, "license": "GPL-3.0" }, From f484dd491b2dc2998e4cfb7616c93c4cabf463f2 Mon Sep 17 00:00:00 2001 From: Conner Turnbull <133619638+cturnbull-bitwarden@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:43:40 -0400 Subject: [PATCH 20/29] [PM-8830] Billing Enums Rename (#9612) * Renamed ProductType to ProductTierType * Renamed Product properties to ProductTier * Moved product-tier-type.enum.ts to billing folder * Added ProductType enum --- .../vault/vault-select.component.html | 4 +- .../vault-popup-items.service.spec.ts | 4 +- .../vault-popup-list-filters.service.spec.ts | 8 +-- .../vault-popup-list-filters.service.ts | 6 +- .../vault/popup/views/popup-cipher.view.ts | 14 ++--- .../member-dialog.component.html | 3 +- .../member-dialog/member-dialog.component.ts | 7 ++- .../org-seat-limit-reached.validator.spec.ts | 10 ++-- .../org-seat-limit-reached.validator.ts | 8 +-- .../organizations/members/people.component.ts | 24 ++++---- ...families-for-enterprise-setup.component.ts | 7 +-- .../settings/create-organization.component.ts | 11 ++-- .../settings/two-factor-setup.component.ts | 4 +- ...ts-manager-trial-paid-stepper.component.ts | 14 ++--- .../trial-initiation.component.ts | 19 +++--- .../trial-billing-step.component.ts | 21 ++++--- .../organization-plans.component.html | 28 +++++---- .../organization-plans.component.ts | 60 ++++++++++--------- ...ganization-subscription-cloud.component.ts | 11 ++-- .../billing/shared/sm-subscribe.component.ts | 14 ++--- .../individual-vault/add-edit.component.ts | 5 +- .../vault-header/vault-header.component.ts | 4 +- .../models/data/organization.data.spec.ts | 4 +- .../models/data/organization.data.ts | 6 +- .../models/domain/organization.ts | 6 +- .../response/profile-organization.response.ts | 4 +- libs/common/src/billing/enums/index.ts | 1 + .../enums/product-tier-type.enum.ts} | 2 +- .../src/billing/enums/product-type.enum.ts | 4 ++ .../billing/models/response/plan.response.ts | 7 +-- libs/common/src/enums/index.ts | 1 - 31 files changed, 164 insertions(+), 157 deletions(-) rename libs/common/src/{enums/product-type.enum.ts => billing/enums/product-tier-type.enum.ts} (72%) create mode 100644 libs/common/src/billing/enums/product-type.enum.ts diff --git a/apps/browser/src/vault/popup/components/vault/vault-select.component.html b/apps/browser/src/vault/popup/components/vault/vault-select.component.html index 84c5f48a4e8..4f6ce3a11e6 100644 --- a/apps/browser/src/vault/popup/components/vault/vault-select.component.html +++ b/apps/browser/src/vault/popup/components/vault/vault-select.component.html @@ -57,12 +57,12 @@ >
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 f08f4e836e1..0b40b136ab9 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 @@ -5,7 +5,7 @@ import { BehaviorSubject } from "rxjs"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { ObservableTracker } from "@bitwarden/common/spec"; import { CipherId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -78,7 +78,7 @@ describe("VaultPopupItemsService", () => { mockOrg = { id: "org1", name: "Organization 1", - planProductType: ProductType.Enterprise, + productTierType: ProductTierType.Enterprise, } as Organization; mockCollections = [ diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts index b89de79a209..f6573de1c80 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts @@ -6,7 +6,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; @@ -206,7 +206,7 @@ describe("VaultPopupListFiltersService", () => { name: "family org", id: "1234-3323-23223", enabled: true, - planProductType: ProductType.Families, + productTierType: ProductTierType.Families, }, ] as Organization[]; @@ -224,7 +224,7 @@ describe("VaultPopupListFiltersService", () => { name: "free org", id: "1234-3323-23223", enabled: true, - planProductType: ProductType.Free, + productTierType: ProductTierType.Free, }, ] as Organization[]; @@ -242,7 +242,7 @@ describe("VaultPopupListFiltersService", () => { name: "free org", id: "1234-3323-23223", enabled: false, - planProductType: ProductType.Free, + productTierType: ProductTierType.Free, }, ] as Organization[]; diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts index 8242637d5de..67213163a64 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts @@ -16,7 +16,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -216,8 +216,8 @@ export class VaultPopupListFiltersService { // Show a warning icon if the organization is deactivated icon = "bwi-exclamation-triangle tw-text-danger"; } else if ( - org.planProductType === ProductType.Families || - org.planProductType === ProductType.Free + org.productTierType === ProductTierType.Families || + org.productTierType === ProductTierType.Free ) { // Show a family icon if the organization is a family or free org icon = "bwi-family"; diff --git a/apps/browser/src/vault/popup/views/popup-cipher.view.ts b/apps/browser/src/vault/popup/views/popup-cipher.view.ts index 4707eb9eb0f..5bb1905c59a 100644 --- a/apps/browser/src/vault/popup/views/popup-cipher.view.ts +++ b/apps/browser/src/vault/popup/views/popup-cipher.view.ts @@ -1,5 +1,5 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; @@ -26,13 +26,13 @@ export class PopupCipherView extends CipherView { * Get the bwi icon for the cipher according to the organization type. */ get orgIcon(): "bwi-family" | "bwi-business" | null { - switch (this.organization?.planProductType) { - case ProductType.Free: - case ProductType.Families: + switch (this.organization?.productTierType) { + case ProductTierType.Free: + case ProductTierType.Families: return "bwi-family"; - case ProductType.Teams: - case ProductType.Enterprise: - case ProductType.TeamsStarter: + case ProductTierType.Teams: + case ProductTierType.Enterprise: + case ProductTierType.TeamsStarter: return "bwi-business"; default: return null; diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html index 9c8d224e6e4..11c1ab2d2e3 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html +++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html @@ -28,7 +28,8 @@ {{ "inviteMultipleEmailDesc" - | i18n: (organization.planProductType === ProductType.TeamsStarter ? "10" : "20") + | i18n + : (organization.productTierType === ProductTierType.TeamsStarter ? "10" : "20") }} diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts index d16435e4d53..81830d12138 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts @@ -22,7 +22,7 @@ import { import { PermissionsApi } from "@bitwarden/common/admin-console/models/api/permissions.api"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -463,7 +463,8 @@ export class MemberDialogComponent implements OnDestroy { await this.userService.save(userView); } else { userView.id = this.params.organizationUserId; - const maxEmailsCount = organization.planProductType === ProductType.TeamsStarter ? 10 : 20; + const maxEmailsCount = + organization.productTierType === ProductTierType.TeamsStarter ? 10 : 20; const emails = [...new Set(this.formGroup.value.emails.trim().split(/\s*,\s*/))]; if (emails.length > maxEmailsCount) { this.formGroup.controls.emails.setErrors({ @@ -614,7 +615,7 @@ export class MemberDialogComponent implements OnDestroy { }); } - protected readonly ProductType = ProductType; + protected readonly ProductTierType = ProductTierType; } function mapCollectionToAccessItemView( diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.spec.ts b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.spec.ts index c26b51e2499..6c693ee8f84 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.spec.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.spec.ts @@ -2,7 +2,7 @@ import { AbstractControl, FormControl, ValidationErrors } from "@angular/forms"; import { OrganizationUserType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { orgSeatLimitReachedValidator } from "./org-seat-limit-reached.validator"; @@ -54,7 +54,7 @@ describe("orgSeatLimitReachedValidator", () => { it("should return null when max seats are not exceeded on free plan", () => { organization = orgFactory({ - planProductType: ProductType.Free, + productTierType: ProductTierType.Free, seats: 2, }); validatorFn = orgSeatLimitReachedValidator( @@ -71,7 +71,7 @@ describe("orgSeatLimitReachedValidator", () => { it("should return null when max seats are not exceeded on teams starter plan", () => { organization = orgFactory({ - planProductType: ProductType.TeamsStarter, + productTierType: ProductTierType.TeamsStarter, seats: 10, }); validatorFn = orgSeatLimitReachedValidator( @@ -98,7 +98,7 @@ describe("orgSeatLimitReachedValidator", () => { it("should return validation error when max seats are exceeded on free plan", () => { organization = orgFactory({ - planProductType: ProductType.Free, + productTierType: ProductTierType.Free, seats: 2, }); const errorMessage = "You cannot invite more than 2 members without upgrading your plan."; @@ -117,7 +117,7 @@ describe("orgSeatLimitReachedValidator", () => { it("should return null when not on free plan", () => { const control = new FormControl("user2@example.com,user3@example.com"); organization = orgFactory({ - planProductType: ProductType.Enterprise, + productTierType: ProductTierType.Enterprise, seats: 100, }); validatorFn = orgSeatLimitReachedValidator( diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.ts b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.ts index 8b521e2c17b..bcd84743918 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/validators/org-seat-limit-reached.validator.ts @@ -1,7 +1,7 @@ import { AbstractControl, ValidationErrors, ValidatorFn } from "@angular/forms"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; /** * If the organization doesn't allow additional seat options, this checks if the seat limit has been reached when adding @@ -37,9 +37,9 @@ export function orgSeatLimitReachedValidator( ); const productHasAdditionalSeatsOption = - organization.planProductType !== ProductType.Free && - organization.planProductType !== ProductType.Families && - organization.planProductType !== ProductType.TeamsStarter; + organization.productTierType !== ProductTierType.Free && + organization.productTierType !== ProductTierType.Families && + organization.productTierType !== ProductTierType.TeamsStarter; return !productHasAdditionalSeatsOption && allOrganizationUserEmails.length + newEmailsToAdd.length > organization.seats diff --git a/apps/web/src/app/admin-console/organizations/members/people.component.ts b/apps/web/src/app/admin-console/organizations/members/people.component.ts index a47e0acd0cd..2349d989955 100644 --- a/apps/web/src/app/admin-console/organizations/members/people.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/people.component.ts @@ -33,7 +33,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; 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"; @@ -335,13 +335,13 @@ export class PeopleComponent extends NewBasePeopleComponent orgs.filter((o) => o.planProductType === ProductType.Families)), + map((orgs) => orgs.filter((o) => o.productTierType === ProductTierType.Families)), ); this.existingFamilyOrganizations$.pipe(takeUntil(this._destroy)).subscribe((orgs) => { diff --git a/apps/web/src/app/admin-console/settings/create-organization.component.ts b/apps/web/src/app/admin-console/settings/create-organization.component.ts index 2a060d6d565..d2bcb9e69c8 100644 --- a/apps/web/src/app/admin-console/settings/create-organization.component.ts +++ b/apps/web/src/app/admin-console/settings/create-organization.component.ts @@ -2,8 +2,7 @@ import { Component, OnInit, ViewChild } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { first } from "rxjs/operators"; -import { PlanType } from "@bitwarden/common/billing/enums"; -import { ProductType } from "@bitwarden/common/enums"; +import { PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; import { OrganizationPlansComponent } from "../../billing"; import { HeaderModule } from "../../layouts/header/header.module"; @@ -26,16 +25,16 @@ export class CreateOrganizationComponent implements OnInit { this.route.queryParams.pipe(first()).subscribe(async (qParams) => { if (qParams.plan === "families") { this.orgPlansComponent.plan = PlanType.FamiliesAnnually; - this.orgPlansComponent.product = ProductType.Families; + this.orgPlansComponent.productTier = ProductTierType.Families; } else if (qParams.plan === "teams") { this.orgPlansComponent.plan = PlanType.TeamsAnnually; - this.orgPlansComponent.product = ProductType.Teams; + this.orgPlansComponent.productTier = ProductTierType.Teams; } else if (qParams.plan === "teamsStarter") { this.orgPlansComponent.plan = PlanType.TeamsStarter; - this.orgPlansComponent.product = ProductType.TeamsStarter; + this.orgPlansComponent.productTier = ProductTierType.TeamsStarter; } else if (qParams.plan === "enterprise") { this.orgPlansComponent.plan = PlanType.EnterpriseAnnually; - this.orgPlansComponent.product = ProductType.Enterprise; + this.orgPlansComponent.productTier = ProductTierType.Enterprise; } }); } 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 34a7e32089f..b1592dc72ac 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 @@ -17,7 +17,7 @@ import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.service"; import { AuthResponse } from "@bitwarden/common/auth/types/auth-response"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { DialogService } from "@bitwarden/components"; @@ -258,6 +258,6 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy { } get isEnterpriseOrg() { - return this.organization?.planProductType === ProductType.Enterprise; + return this.organization?.productTierType === ProductTierType.Enterprise; } } diff --git a/apps/web/src/app/auth/trial-initiation/secrets-manager/secrets-manager-trial-paid-stepper.component.ts b/apps/web/src/app/auth/trial-initiation/secrets-manager/secrets-manager-trial-paid-stepper.component.ts index 0f4fd5110bc..e61b7fc7776 100644 --- a/apps/web/src/app/auth/trial-initiation/secrets-manager/secrets-manager-trial-paid-stepper.component.ts +++ b/apps/web/src/app/auth/trial-initiation/secrets-manager/secrets-manager-trial-paid-stepper.component.ts @@ -1,6 +1,6 @@ import { Component, Input, ViewChild } from "@angular/core"; -import { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { OrganizationCreatedEvent, @@ -33,22 +33,22 @@ export class SecretsManagerTrialPaidStepperComponent extends SecretsManagerTrial get createAccountLabel() { const organizationType = - this.productType === ProductType.TeamsStarter + this.productType === ProductTierType.TeamsStarter ? "Teams Starter" - : ProductType[this.productType]; + : ProductTierType[this.productType]; return `Before creating your ${organizationType} organization, you first need to log in or create a personal account.`; } get productType(): TrialOrganizationType { switch (this.organizationTypeQueryParameter) { case "enterprise": - return ProductType.Enterprise; + return ProductTierType.Enterprise; case "families": - return ProductType.Families; + return ProductTierType.Families; case "teams": - return ProductType.Teams; + return ProductTierType.Teams; case "teamsStarter": - return ProductType.TeamsStarter; + return ProductTierType.TeamsStarter; } } diff --git a/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts b/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts index d02b2c9e2ea..f8718b0a420 100644 --- a/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts +++ b/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts @@ -9,8 +9,7 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; -import { PlanType } from "@bitwarden/common/billing/enums"; -import { ProductType } from "@bitwarden/common/enums"; +import { PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -67,7 +66,7 @@ export class TrialInitiationComponent implements OnInit, OnDestroy { billingSubLabel = ""; layout = "default"; plan: PlanType; - product: ProductType; + productTier: ProductTierType; accountCreateOnly = true; useTrialStepper = false; policies: Policy[]; @@ -153,16 +152,16 @@ export class TrialInitiationComponent implements OnInit, OnDestroy { if (this.org === ValidOrgParams.families) { this.plan = PlanType.FamiliesAnnually; - this.product = ProductType.Families; + this.productTier = ProductTierType.Families; } else if (this.org === ValidOrgParams.teamsStarter) { this.plan = PlanType.TeamsStarter; - this.product = ProductType.TeamsStarter; + this.productTier = ProductTierType.TeamsStarter; } else if (this.org === ValidOrgParams.teams) { this.plan = PlanType.TeamsAnnually; - this.product = ProductType.Teams; + this.productTier = ProductTierType.Teams; } else if (this.org === ValidOrgParams.enterprise) { this.plan = PlanType.EnterpriseAnnually; - this.product = ProductType.Enterprise; + this.productTier = ProductTierType.Enterprise; } } else if (this.routeFlowOrgs.includes(qParams.org)) { this.referenceData.flow = qParams.org; @@ -268,11 +267,11 @@ export class TrialInitiationComponent implements OnInit, OnDestroy { } get trialOrganizationType(): TrialOrganizationType { - switch (this.product) { - case ProductType.Free: + switch (this.productTier) { + case ProductTierType.Free: return null; default: - return this.product; + return this.productTier; } } diff --git a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts index bd138cad292..0be4f614d0e 100644 --- a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts +++ b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts @@ -9,16 +9,15 @@ import { PaymentInformation, PlanInformation, } from "@bitwarden/common/billing/abstractions/organization-billing.service"; -import { PaymentMethodType, PlanType } from "@bitwarden/common/billing/enums"; +import { PaymentMethodType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; -import { ProductType } from "@bitwarden/common/enums"; 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 { BillingSharedModule, PaymentComponent, TaxInfoComponent } from "../../shared"; -export type TrialOrganizationType = Exclude; +export type TrialOrganizationType = Exclude; export interface OrganizationInfo { name: string; @@ -176,19 +175,19 @@ export class TrialBillingStepComponent implements OnInit { [cadence in SubscriptionCadence]?: PlanType; }; } = { - [ProductType.Enterprise]: { + [ProductTierType.Enterprise]: { [SubscriptionCadence.Annual]: PlanType.EnterpriseAnnually, [SubscriptionCadence.Monthly]: PlanType.EnterpriseMonthly, }, - [ProductType.Families]: { + [ProductTierType.Families]: { [SubscriptionCadence.Annual]: PlanType.FamiliesAnnually, // No monthly option for Families plan }, - [ProductType.Teams]: { + [ProductTierType.Teams]: { [SubscriptionCadence.Annual]: PlanType.TeamsAnnually, [SubscriptionCadence.Monthly]: PlanType.TeamsMonthly, }, - [ProductType.TeamsStarter]: { + [ProductTierType.TeamsStarter]: { // No annual option for Teams Starter plan [SubscriptionCadence.Monthly]: PlanType.TeamsStarter, }, @@ -233,10 +232,10 @@ export class TrialBillingStepComponent implements OnInit { private isApplicable(plan: PlanResponse): boolean { const hasCorrectProductType = - plan.product === ProductType.Enterprise || - plan.product === ProductType.Families || - plan.product === ProductType.Teams || - plan.product === ProductType.TeamsStarter; + plan.productTier === ProductTierType.Enterprise || + plan.productTier === ProductTierType.Families || + plan.productTier === ProductTierType.Teams || + plan.productTier === ProductTierType.TeamsStarter; const notDisabledOrLegacy = !plan.disabled && !plan.legacyYear; return hasCorrectProductType && notDisabledOrLegacy; } diff --git a/apps/web/src/app/billing/organizations/organization-plans.component.html b/apps/web/src/app/billing/organizations/organization-plans.component.html index 1bd6b99dd17..227552119a3 100644 --- a/apps/web/src/app/billing/organizations/organization-plans.component.html +++ b/apps/web/src/app/billing/organizations/organization-plans.component.html @@ -51,14 +51,17 @@

{{ "chooseYourPlan" | i18n }}

- +
- + {{ selectableProduct.nameLocalizationKey | i18n }} {{ selectableProduct.descriptionLocalizationKey | i18n: "1" }}
  • {{ "includeAllTeamsFeatures" | i18n }}
  • @@ -75,7 +78,8 @@ @@ -90,13 +94,13 @@
      -
    • +
    • {{ "limitedUsers" | i18n: selectableProduct.PasswordManager.maxSeats }}
    • @@ -136,7 +140,7 @@ {{ "onPremHostingOptional" | i18n }}
    • {{ "usersGetPremium" | i18n }}
    • -
    • +
    • {{ "priorityCustomerSupport" | i18n }}
    • @@ -147,7 +151,7 @@ - + @@ -189,13 +193,13 @@ }} /{{ "month" | i18n }} - {{ + {{ "freeForever" | i18n }}
- + +

{{ (createOrganization ? "paymentInformation" : "billingInformation") | i18n }}

diff --git a/apps/web/src/app/billing/organizations/organization-plans.component.ts b/apps/web/src/app/billing/organizations/organization-plans.component.ts index 2228ad9f3ad..05e22323320 100644 --- a/apps/web/src/app/billing/organizations/organization-plans.component.ts +++ b/apps/web/src/app/billing/organizations/organization-plans.component.ts @@ -23,12 +23,11 @@ import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/ import { OrganizationUpgradeRequest } from "@bitwarden/common/admin-console/models/request/organization-upgrade.request"; import { ProviderOrganizationCreateRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-organization-create.request"; import { ProviderResponse } from "@bitwarden/common/admin-console/models/response/provider/provider.response"; -import { PaymentMethodType, PlanType } from "@bitwarden/common/billing/enums"; +import { PaymentMethodType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; import { PaymentRequest } from "@bitwarden/common/billing/models/request/payment.request"; import { BillingResponse } from "@bitwarden/common/billing/models/response/billing.response"; import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response"; import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; -import { ProductType } from "@bitwarden/common/enums"; 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"; @@ -73,16 +72,16 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { selectedFile: File; @Input() - get product(): ProductType { - return this._product; + get productTier(): ProductTierType { + return this._productTier; } - set product(product: ProductType) { - this._product = product; - this.formGroup?.controls?.product?.setValue(product); + set productTier(product: ProductTierType) { + this._productTier = product; + this.formGroup?.controls?.productTier?.setValue(product); } - private _product = ProductType.Free; + private _productTier = ProductTierType.Free; @Input() get plan(): PlanType { @@ -102,7 +101,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { loading = true; selfHosted = false; - productTypes = ProductType; + productTypes = ProductTierType; formPromise: Promise; singleOrgPolicyAppliesToActiveUser = false; isInTrialFlow = false; @@ -123,7 +122,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { additionalSeats: [0, [Validators.min(0), Validators.max(100000)]], clientOwnerEmail: ["", [Validators.email]], plan: [this.plan], - product: [this.product], + productTier: [this.productTier], secretsManager: this.secretsManagerSubscription, }); @@ -166,20 +165,23 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { this.passwordManagerPlans = plans.data.filter((plan) => !!plan.PasswordManager); this.secretsManagerPlans = plans.data.filter((plan) => !!plan.SecretsManager); - if (this.product === ProductType.Enterprise || this.product === ProductType.Teams) { + if ( + this.productTier === ProductTierType.Enterprise || + this.productTier === ProductTierType.Teams + ) { this.formGroup.controls.businessOwned.setValue(true); } } - if (this.currentPlan && this.currentPlan.product !== ProductType.Enterprise) { + if (this.currentPlan && this.currentPlan.productTier !== ProductTierType.Enterprise) { const upgradedPlan = this.passwordManagerPlans.find((plan) => - this.currentPlan.product === ProductType.Free + this.currentPlan.productTier === ProductTierType.Free ? plan.type === PlanType.FamiliesAnnually : plan.upgradeSortOrder == this.currentPlan.upgradeSortOrder + 1, ); this.plan = upgradedPlan.type; - this.product = upgradedPlan.product; + this.productTier = upgradedPlan.productTier; } if (this.hasProvider) { @@ -190,7 +192,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { (plan) => plan.type === PlanType.TeamsAnnually, ); this.plan = providerDefaultPlan.type; - this.product = providerDefaultPlan.product; + this.productTier = providerDefaultPlan.productTier; } if (!this.createOrganization) { @@ -229,7 +231,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { get upgradeRequiresPaymentMethod() { return ( - this.organization?.planProductType === ProductType.Free && + this.organization?.productTierType === ProductTierType.Free && !this.showFree && !this.billing?.paymentSource ); @@ -277,12 +279,12 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { (plan) => plan.type !== PlanType.Custom && (!businessOwnedIsChecked || plan.canBeUsedByBusiness) && - (this.showFree || plan.product !== ProductType.Free) && + (this.showFree || plan.productTier !== ProductTierType.Free) && (plan.isAnnual || - plan.product === ProductType.Free || - plan.product === ProductType.TeamsStarter) && + plan.productTier === ProductTierType.Free || + plan.productTier === ProductTierType.TeamsStarter) && (!this.currentPlan || this.currentPlan.upgradeSortOrder < plan.upgradeSortOrder) && - (!this.hasProvider || plan.product !== ProductType.TeamsStarter) && + (!this.hasProvider || plan.productTier !== ProductTierType.TeamsStarter) && ((!this.isProviderQualifiedFor2020Plan() && this.planIsEnabled(plan)) || (this.isProviderQualifiedFor2020Plan() && Allowed2020PlansForLegacyProviders.includes(plan.type))), @@ -294,11 +296,11 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { } get selectablePlans() { - const selectedProductType = this.formGroup.controls.product.value; + const selectedProductTierType = this.formGroup.controls.productTier.value; const result = this.passwordManagerPlans?.filter( (plan) => - plan.product === selectedProductType && + plan.productTier === selectedProductTierType && ((!this.isProviderQualifiedFor2020Plan() && this.planIsEnabled(plan)) || (this.isProviderQualifiedFor2020Plan() && Allowed2020PlansForLegacyProviders.includes(plan.type))), @@ -516,10 +518,10 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { return; } if (this.teamsStarterPlanIsAvailable) { - this.formGroup.controls.product.setValue(ProductType.TeamsStarter); + this.formGroup.controls.productTier.setValue(ProductTierType.TeamsStarter); this.formGroup.controls.plan.setValue(PlanType.TeamsStarter); } else { - this.formGroup.controls.product.setValue(ProductType.Teams); + this.formGroup.controls.productTier.setValue(ProductTierType.Teams); this.formGroup.controls.plan.setValue(PlanType.TeamsAnnually); } this.changedProduct(); @@ -766,19 +768,19 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { private upgradeFlowPrefillForm() { if (this.acceptingSponsorship) { - this.formGroup.controls.product.setValue(ProductType.Families); + this.formGroup.controls.productTier.setValue(ProductTierType.Families); this.changedProduct(); return; } - if (this.currentPlan && this.currentPlan.product !== ProductType.Enterprise) { + if (this.currentPlan && this.currentPlan.productTier !== ProductTierType.Enterprise) { const upgradedPlan = this.passwordManagerPlans.find((plan) => { - if (this.currentPlan.product === ProductType.Free) { + if (this.currentPlan.productTier === ProductTierType.Free) { return plan.type === PlanType.FamiliesAnnually; } if ( - this.currentPlan.product === ProductType.Families && + this.currentPlan.productTier === ProductTierType.Families && !this.teamsStarterPlanIsAvailable ) { return plan.type === PlanType.TeamsAnnually; @@ -788,7 +790,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { }); this.plan = upgradedPlan.type; - this.product = upgradedPlan.product; + this.productTier = upgradedPlan.productTier; this.changedProduct(); } } diff --git a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts index b6282f1e7b1..d8568d15b5c 100644 --- a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts +++ b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts @@ -8,10 +8,9 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; import { OrganizationApiKeyType, ProviderStatusType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { PlanType } from "@bitwarden/common/billing/enums"; +import { PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response"; import { BillingSubscriptionItemResponse } from "@bitwarden/common/billing/models/response/subscription.response"; -import { ProductType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -53,7 +52,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy manageBillingFromProviderPortal = ManageBilling; isProviderManaged = false; - protected readonly teamsStarter = ProductType.TeamsStarter; + protected readonly teamsStarter = ProductTierType.TeamsStarter; private destroy$ = new Subject(); @@ -286,7 +285,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy } } else if (this.sub.maxAutoscaleSeats === this.sub.seats && this.sub.seats != null) { return this.i18nService.t("subscriptionMaxReached", this.sub.seats.toString()); - } else if (this.userOrg.planProductType === ProductType.TeamsStarter) { + } else if (this.userOrg.productTierType === ProductTierType.TeamsStarter) { return this.i18nService.t("subscriptionUserSeatsWithoutAdditionalSeatsOption", 10); } else if (this.sub.maxAutoscaleSeats == null) { return this.i18nService.t("subscriptionUserSeatsUnlimitedAutoscale"); @@ -440,12 +439,12 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy }; get showChangePlanButton() { - return this.sub.plan.product !== ProductType.Enterprise && !this.showChangePlan; + return this.sub.plan.productTier !== ProductTierType.Enterprise && !this.showChangePlan; } } /** - * Helper to sort subscription items by product type and then by addon status + * Helper to sort subscription items by productTier type and then by addon status */ function sortSubscriptionItems( a: BillingSubscriptionItemResponse, diff --git a/apps/web/src/app/billing/shared/sm-subscribe.component.ts b/apps/web/src/app/billing/shared/sm-subscribe.component.ts index a849b8dd335..7bb3e3cada0 100644 --- a/apps/web/src/app/billing/shared/sm-subscribe.component.ts +++ b/apps/web/src/app/billing/shared/sm-subscribe.component.ts @@ -3,9 +3,9 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { Subject, startWith, takeUntil } from "rxjs"; import { ControlsOf } from "@bitwarden/angular/types/controls-of"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { BillingCustomerDiscount } from "@bitwarden/common/billing/models/response/organization-subscription.response"; import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; -import { ProductType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { SecretsManagerLogo } from "../../layouts/secrets-manager-logo"; @@ -40,7 +40,7 @@ export class SecretsManagerSubscribeComponent implements OnInit, OnDestroy { @Input() customerDiscount: BillingCustomerDiscount; logo = SecretsManagerLogo; - productTypes = ProductType; + productTypes = ProductTierType; private destroy$ = new Subject(); @@ -75,17 +75,17 @@ export class SecretsManagerSubscribeComponent implements OnInit, OnDestroy { }; get product() { - return this.selectedPlan.product; + return this.selectedPlan.productTier; } get planName() { switch (this.product) { - case ProductType.Free: + case ProductTierType.Free: return this.i18nService.t("free2PersonOrganization"); - case ProductType.Teams: - case ProductType.TeamsStarter: + case ProductTierType.Teams: + case ProductTierType.TeamsStarter: return this.i18nService.t("planNameTeams"); - case ProductType.Enterprise: + case ProductTierType.Enterprise: return this.i18nService.t("planNameEnterprise"); } } 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 fee728ca995..8b29595063e 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 @@ -9,7 +9,8 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; -import { EventType, ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; +import { EventType } from "@bitwarden/common/enums"; 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"; @@ -271,7 +272,7 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On return ( this.cipher.type === CipherType.Login && this.cipher.login.totp && - this.organization?.planProductType != ProductType.Free && + this.organization?.productTierType != ProductTierType.Free && (this.cipher.organizationUseTotp || this.canAccessPremium) ); } diff --git a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts index 729e174f760..081d1e503e8 100644 --- a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts +++ b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts @@ -4,7 +4,7 @@ import { firstValueFrom } 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 { ProductType } from "@bitwarden/common/enums"; +import { ProductTierType } from "@bitwarden/common/billing/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -183,7 +183,7 @@ export class VaultHeaderComponent implements OnInit { } async addCollection() { - if (this.organization.planProductType === ProductType.Free) { + if (this.organization.productTierType === ProductTierType.Free) { const collections = await this.collectionAdminService.getAll(this.organization.id); if (collections.length === this.organization.maxCollections) { this.showFreeOrgUpgradeDialog(); diff --git a/libs/common/src/admin-console/models/data/organization.data.spec.ts b/libs/common/src/admin-console/models/data/organization.data.spec.ts index 18680483906..549c759f939 100644 --- a/libs/common/src/admin-console/models/data/organization.data.spec.ts +++ b/libs/common/src/admin-console/models/data/organization.data.spec.ts @@ -1,4 +1,4 @@ -import { ProductType } from "../../../enums/product-type.enum"; +import { ProductTierType } from "../../../billing/enums/product-tier-type.enum"; import { OrganizationUserStatusType, OrganizationUserType } from "../../enums"; import { ORGANIZATIONS } from "../../services/organization/organization.service"; @@ -47,7 +47,7 @@ describe("ORGANIZATIONS state", () => { isMember: false, familySponsorshipFriendlyName: "fsfn", familySponsorshipAvailable: false, - planProductType: ProductType.Free, + productTierType: ProductTierType.Free, keyConnectorEnabled: false, keyConnectorUrl: "kcu", accessSecretsManager: false, diff --git a/libs/common/src/admin-console/models/data/organization.data.ts b/libs/common/src/admin-console/models/data/organization.data.ts index afc6b40b934..2b27882cb70 100644 --- a/libs/common/src/admin-console/models/data/organization.data.ts +++ b/libs/common/src/admin-console/models/data/organization.data.ts @@ -1,6 +1,6 @@ import { Jsonify } from "type-fest"; -import { ProductType } from "../../../enums"; +import { ProductTierType } from "../../../billing/enums"; import { OrganizationUserStatusType, OrganizationUserType, ProviderType } from "../../enums"; import { PermissionsApi } from "../api/permissions.api"; import { ProfileOrganizationResponse } from "../response/profile-organization.response"; @@ -45,7 +45,7 @@ export class OrganizationData { isMember: boolean; familySponsorshipFriendlyName: string; familySponsorshipAvailable: boolean; - planProductType: ProductType; + productTierType: ProductTierType; keyConnectorEnabled: boolean; keyConnectorUrl: string; familySponsorshipLastSyncDate?: Date; @@ -104,7 +104,7 @@ export class OrganizationData { this.providerType = response.providerType; this.familySponsorshipFriendlyName = response.familySponsorshipFriendlyName; this.familySponsorshipAvailable = response.familySponsorshipAvailable; - this.planProductType = response.planProductType; + this.productTierType = response.planProductType; this.keyConnectorEnabled = response.keyConnectorEnabled; this.keyConnectorUrl = response.keyConnectorUrl; this.familySponsorshipLastSyncDate = response.familySponsorshipLastSyncDate; diff --git a/libs/common/src/admin-console/models/domain/organization.ts b/libs/common/src/admin-console/models/domain/organization.ts index f18167f7331..d8e90e41be7 100644 --- a/libs/common/src/admin-console/models/domain/organization.ts +++ b/libs/common/src/admin-console/models/domain/organization.ts @@ -1,6 +1,6 @@ import { Jsonify } from "type-fest"; -import { ProductType } from "../../../enums"; +import { ProductTierType } from "../../../billing/enums"; import { OrganizationUserStatusType, OrganizationUserType, ProviderType } from "../../enums"; import { PermissionsApi } from "../api/permissions.api"; import { OrganizationData } from "../data/organization.data"; @@ -58,7 +58,7 @@ export class Organization { isMember: boolean; familySponsorshipFriendlyName: string; familySponsorshipAvailable: boolean; - planProductType: ProductType; + productTierType: ProductTierType; keyConnectorEnabled: boolean; keyConnectorUrl: string; familySponsorshipLastSyncDate?: Date; @@ -123,7 +123,7 @@ export class Organization { this.isMember = obj.isMember; this.familySponsorshipFriendlyName = obj.familySponsorshipFriendlyName; this.familySponsorshipAvailable = obj.familySponsorshipAvailable; - this.planProductType = obj.planProductType; + this.productTierType = obj.productTierType; this.keyConnectorEnabled = obj.keyConnectorEnabled; this.keyConnectorUrl = obj.keyConnectorUrl; this.familySponsorshipLastSyncDate = obj.familySponsorshipLastSyncDate; diff --git a/libs/common/src/admin-console/models/response/profile-organization.response.ts b/libs/common/src/admin-console/models/response/profile-organization.response.ts index 1649bf47ba6..6a469005db1 100644 --- a/libs/common/src/admin-console/models/response/profile-organization.response.ts +++ b/libs/common/src/admin-console/models/response/profile-organization.response.ts @@ -1,4 +1,4 @@ -import { ProductType } from "../../../enums"; +import { ProductTierType } from "../../../billing/enums"; import { BaseResponse } from "../../../models/response/base.response"; import { OrganizationUserStatusType, OrganizationUserType, ProviderType } from "../../enums"; import { PermissionsApi } from "../api/permissions.api"; @@ -42,7 +42,7 @@ export class ProfileOrganizationResponse extends BaseResponse { providerType?: ProviderType; familySponsorshipFriendlyName: string; familySponsorshipAvailable: boolean; - planProductType: ProductType; + planProductType: ProductTierType; keyConnectorEnabled: boolean; keyConnectorUrl: string; familySponsorshipLastSyncDate?: Date; diff --git a/libs/common/src/billing/enums/index.ts b/libs/common/src/billing/enums/index.ts index 70a3495a8bf..e11cd9d8294 100644 --- a/libs/common/src/billing/enums/index.ts +++ b/libs/common/src/billing/enums/index.ts @@ -3,3 +3,4 @@ export * from "./plan-sponsorship-type.enum"; export * from "./plan-type.enum"; export * from "./transaction-type.enum"; export * from "./bitwarden-product-type.enum"; +export * from "./product-tier-type.enum"; diff --git a/libs/common/src/enums/product-type.enum.ts b/libs/common/src/billing/enums/product-tier-type.enum.ts similarity index 72% rename from libs/common/src/enums/product-type.enum.ts rename to libs/common/src/billing/enums/product-tier-type.enum.ts index 7ed3a79e988..c40f913ec82 100644 --- a/libs/common/src/enums/product-type.enum.ts +++ b/libs/common/src/billing/enums/product-tier-type.enum.ts @@ -1,4 +1,4 @@ -export enum ProductType { +export enum ProductTierType { Free = 0, Families = 1, Teams = 2, diff --git a/libs/common/src/billing/enums/product-type.enum.ts b/libs/common/src/billing/enums/product-type.enum.ts new file mode 100644 index 00000000000..3072ad0f96a --- /dev/null +++ b/libs/common/src/billing/enums/product-type.enum.ts @@ -0,0 +1,4 @@ +export enum ProductType { + PasswordManager = 0, + SecretsManager = 1, +} diff --git a/libs/common/src/billing/models/response/plan.response.ts b/libs/common/src/billing/models/response/plan.response.ts index 9f603840c36..c03fd76efc7 100644 --- a/libs/common/src/billing/models/response/plan.response.ts +++ b/libs/common/src/billing/models/response/plan.response.ts @@ -1,10 +1,9 @@ -import { ProductType } from "../../../enums"; +import { ProductTierType, PlanType } from "../../../billing/enums"; import { BaseResponse } from "../../../models/response/base.response"; -import { PlanType } from "../../enums"; export class PlanResponse extends BaseResponse { type: PlanType; - product: ProductType; + productTier: ProductTierType; name: string; isAnnual: boolean; nameLocalizationKey: string; @@ -32,7 +31,7 @@ export class PlanResponse extends BaseResponse { constructor(response: any) { super(response); this.type = this.getResponseProperty("Type"); - this.product = this.getResponseProperty("Product"); + this.productTier = this.getResponseProperty("ProductTier"); this.name = this.getResponseProperty("Name"); this.isAnnual = this.getResponseProperty("IsAnnual"); this.nameLocalizationKey = this.getResponseProperty("NameLocalizationKey"); diff --git a/libs/common/src/enums/index.ts b/libs/common/src/enums/index.ts index 9ca806899a1..cf9dac80189 100644 --- a/libs/common/src/enums/index.ts +++ b/libs/common/src/enums/index.ts @@ -6,4 +6,3 @@ export * from "./http-status-code.enum"; export * from "./integration-type.enum"; export * from "./native-messaging-version.enum"; export * from "./notification-type.enum"; -export * from "./product-type.enum"; From e38a39f7c6eefcb06e6be1f00081413c44ea136d Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:50:05 -0700 Subject: [PATCH 21/29] adjust w (#9657) --- apps/web/src/app/auth/login/login.component.html | 1 - libs/auth/src/angular/anon-layout/anon-layout.component.html | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/web/src/app/auth/login/login.component.html b/apps/web/src/app/auth/login/login.component.html index 9f2939ed452..dae5918e40c 100644 --- a/apps/web/src/app/auth/login/login.component.html +++ b/apps/web/src/app/auth/login/login.component.html @@ -2,7 +2,6 @@ [bitSubmit]="submitForm.bind(null, false)" [appApiAction]="formPromise" [formGroup]="formGroup" - class="tw-w-96" >
diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.html b/libs/auth/src/angular/anon-layout/anon-layout.component.html index b6eeb70d5d5..8fed6a82266 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.html +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.html @@ -14,10 +14,10 @@

{{ subtitle }}

From 1043a582c1426e04917dfc0657a5deb6fe5784cb Mon Sep 17 00:00:00 2001 From: Jake Fink Date: Fri, 14 Jun 2024 16:06:55 -0400 Subject: [PATCH 22/29] [PM-7879, PM-7635] Add server verification for master password to user verification (#9523) * add MP server verification * add tests and minor service enhancements * fix tests * fix initializations for cli and browser * fix CLI * pr feedback --- .../browser/src/background/main.background.ts | 1 - apps/cli/src/auth/commands/unlock.command.ts | 98 ++-- apps/cli/src/base-program.ts | 4 +- apps/cli/src/oss-serve-configurator.ts | 4 +- apps/cli/src/program.ts | 4 +- apps/cli/src/service-container.ts | 1 - .../src/auth/components/lock.component.ts | 73 ++- .../src/services/jslib-services.module.ts | 1 - libs/common/src/abstractions/api.service.ts | 4 - ...er-verification-api.service.abstraction.ts | 5 + .../user-verification.service.abstraction.ts | 57 ++- .../user-verification-api.service.ts | 7 + .../user-verification.service.spec.ts | 418 ++++++++++++++++++ .../user-verification.service.ts | 99 +++-- libs/common/src/auth/types/verification.ts | 7 + libs/common/src/services/api.service.ts | 7 - 16 files changed, 617 insertions(+), 173 deletions(-) create mode 100644 libs/common/src/auth/services/user-verification/user-verification.service.spec.ts diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 3aabde40656..8e11e7e193e 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -745,7 +745,6 @@ export default class MainBackground { this.folderApiService = new FolderApiService(this.folderService, this.apiService); this.userVerificationService = new UserVerificationService( - this.stateService, this.cryptoService, this.accountService, this.masterPasswordService, diff --git a/apps/cli/src/auth/commands/unlock.command.ts b/apps/cli/src/auth/commands/unlock.command.ts index e3bb9257fac..d767ee80b37 100644 --- a/apps/cli/src/auth/commands/unlock.command.ts +++ b/apps/cli/src/auth/commands/unlock.command.ts @@ -1,19 +1,18 @@ import { firstValueFrom, map } from "rxjs"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; -import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; +import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; +import { MasterPasswordVerification } from "@bitwarden/common/auth/types/verification"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { HashPurpose } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; +import { MasterKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { ConvertToKeyConnectorCommand } from "../../commands/convert-to-key-connector.command"; @@ -26,16 +25,14 @@ export class UnlockCommand { private accountService: AccountService, private masterPasswordService: InternalMasterPasswordServiceAbstraction, private cryptoService: CryptoService, - private stateService: StateService, + private userVerificationService: UserVerificationService, private cryptoFunctionService: CryptoFunctionService, - private apiService: ApiService, private logService: ConsoleLogService, private keyConnectorService: KeyConnectorService, private environmentService: EnvironmentService, private syncService: SyncService, private organizationApiService: OrganizationApiServiceAbstraction, private logout: () => Promise, - private kdfConfigService: KdfConfigService, ) {} async run(password: string, cmdOptions: Record) { @@ -52,62 +49,43 @@ export class UnlockCommand { const [userId, email] = await firstValueFrom( this.accountService.activeAccount$.pipe(map((a) => [a?.id, a?.email])), ); - const kdfConfig = await this.kdfConfigService.getKdfConfig(); - const masterKey = await this.cryptoService.makeMasterKey(password, email, kdfConfig); - const storedMasterKeyHash = await firstValueFrom( - this.masterPasswordService.masterKeyHash$(userId), - ); - let passwordValid = false; - if (masterKey != null) { - if (storedMasterKeyHash != null) { - passwordValid = await this.cryptoService.compareAndUpdateKeyHash(password, masterKey); - } else { - const serverKeyHash = await this.cryptoService.hashMasterKey( - password, - masterKey, - HashPurpose.ServerAuthorization, - ); - const request = new SecretVerificationRequest(); - request.masterPasswordHash = serverKeyHash; - try { - await this.apiService.postAccountVerifyPassword(request); - passwordValid = true; - const localKeyHash = await this.cryptoService.hashMasterKey( - password, - masterKey, - HashPurpose.LocalAuthorization, - ); - await this.masterPasswordService.setMasterKeyHash(localKeyHash, userId); - } catch { - // Ignore - } + const verification = { + type: VerificationType.MasterPassword, + secret: password, + } as MasterPasswordVerification; + + let masterKey: MasterKey; + try { + const response = await this.userVerificationService.verifyUserByMasterPassword( + verification, + userId, + email, + ); + masterKey = response.masterKey; + } catch (e) { + // verification failure throws + return Response.error(e.message); + } + + const userKey = await this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey); + await this.cryptoService.setUserKey(userKey); + + if (await this.keyConnectorService.getConvertAccountRequired()) { + const convertToKeyConnectorCommand = new ConvertToKeyConnectorCommand( + this.keyConnectorService, + this.environmentService, + this.syncService, + this.organizationApiService, + this.logout, + ); + const convertResponse = await convertToKeyConnectorCommand.run(); + if (!convertResponse.success) { + return convertResponse; } } - if (passwordValid) { - await this.masterPasswordService.setMasterKey(masterKey, userId); - const userKey = await this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey); - await this.cryptoService.setUserKey(userKey); - - if (await this.keyConnectorService.getConvertAccountRequired()) { - const convertToKeyConnectorCommand = new ConvertToKeyConnectorCommand( - this.keyConnectorService, - this.environmentService, - this.syncService, - this.organizationApiService, - this.logout, - ); - const convertResponse = await convertToKeyConnectorCommand.run(); - if (!convertResponse.success) { - return convertResponse; - } - } - - return this.successResponse(); - } else { - return Response.error("Invalid master password."); - } + return this.successResponse(); } private async setNewSessionKey() { diff --git a/apps/cli/src/base-program.ts b/apps/cli/src/base-program.ts index 46aadc323c3..563b205fa74 100644 --- a/apps/cli/src/base-program.ts +++ b/apps/cli/src/base-program.ts @@ -140,16 +140,14 @@ export abstract class BaseProgram { this.serviceContainer.accountService, this.serviceContainer.masterPasswordService, this.serviceContainer.cryptoService, - this.serviceContainer.stateService, + this.serviceContainer.userVerificationService, this.serviceContainer.cryptoFunctionService, - this.serviceContainer.apiService, this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, this.serviceContainer.syncService, this.serviceContainer.organizationApiService, this.serviceContainer.logout, - this.serviceContainer.kdfConfigService, ); const response = await command.run(null, null); if (!response.success) { diff --git a/apps/cli/src/oss-serve-configurator.ts b/apps/cli/src/oss-serve-configurator.ts index 970be7a4bb9..13f50da78b7 100644 --- a/apps/cli/src/oss-serve-configurator.ts +++ b/apps/cli/src/oss-serve-configurator.ts @@ -120,16 +120,14 @@ export class OssServeConfigurator { this.serviceContainer.accountService, this.serviceContainer.masterPasswordService, this.serviceContainer.cryptoService, - this.serviceContainer.stateService, + this.serviceContainer.userVerificationService, this.serviceContainer.cryptoFunctionService, - this.serviceContainer.apiService, this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, this.serviceContainer.syncService, this.serviceContainer.organizationApiService, async () => await this.serviceContainer.logout(), - this.serviceContainer.kdfConfigService, ); this.sendCreateCommand = new SendCreateCommand( diff --git a/apps/cli/src/program.ts b/apps/cli/src/program.ts index b8ddca11de3..37c838b6646 100644 --- a/apps/cli/src/program.ts +++ b/apps/cli/src/program.ts @@ -270,16 +270,14 @@ export class Program extends BaseProgram { this.serviceContainer.accountService, this.serviceContainer.masterPasswordService, this.serviceContainer.cryptoService, - this.serviceContainer.stateService, + this.serviceContainer.userVerificationService, this.serviceContainer.cryptoFunctionService, - this.serviceContainer.apiService, this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, this.serviceContainer.syncService, this.serviceContainer.organizationApiService, async () => await this.serviceContainer.logout(), - this.serviceContainer.kdfConfigService, ); const response = await command.run(password, cmd); this.processResponse(response); diff --git a/apps/cli/src/service-container.ts b/apps/cli/src/service-container.ts index 8749eeb982f..2d5f83787f1 100644 --- a/apps/cli/src/service-container.ts +++ b/apps/cli/src/service-container.ts @@ -613,7 +613,6 @@ export class ServiceContainer { await this.cryptoService.clearStoredUserKey(KeySuffixOptions.Auto); this.userVerificationService = new UserVerificationService( - this.stateService, this.cryptoService, this.accountService, this.masterPasswordService, diff --git a/libs/angular/src/auth/components/lock.component.ts b/libs/angular/src/auth/components/lock.component.ts index 64cd664f1f3..88b042c5b8e 100644 --- a/libs/angular/src/auth/components/lock.component.ts +++ b/libs/angular/src/auth/components/lock.component.ts @@ -17,9 +17,12 @@ import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; -import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request"; -import { MasterPasswordPolicyResponse } from "@bitwarden/common/auth/models/response/master-password-policy.response"; +import { + MasterPasswordVerification, + MasterPasswordVerificationResponse, +} from "@bitwarden/common/auth/types/verification"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; @@ -29,7 +32,7 @@ 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 { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; -import { HashPurpose, KeySuffixOptions } from "@bitwarden/common/platform/enums"; +import { KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; @@ -45,7 +48,7 @@ export class LockComponent implements OnInit, OnDestroy { pinEnabled = false; masterPasswordEnabled = false; webVaultHostname = ""; - formPromise: Promise; + formPromise: Promise; supportsBiometric: boolean; biometricLock: boolean; @@ -218,51 +221,30 @@ export class LockComponent implements OnInit, OnDestroy { } private async doUnlockWithMasterPassword() { - const kdfConfig = await this.kdfConfigService.getKdfConfig(); const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; - const masterKey = await this.cryptoService.makeMasterKey( - this.masterPassword, - this.email, - kdfConfig, - ); - const storedMasterKeyHash = await firstValueFrom( - this.masterPasswordService.masterKeyHash$(userId), - ); + const verification = { + type: VerificationType.MasterPassword, + secret: this.masterPassword, + } as MasterPasswordVerification; let passwordValid = false; - - if (storedMasterKeyHash != null) { - // Offline unlock possible - passwordValid = await this.cryptoService.compareAndUpdateKeyHash( - this.masterPassword, - masterKey, + let response: MasterPasswordVerificationResponse; + try { + this.formPromise = this.userVerificationService.verifyUserByMasterPassword( + verification, + userId, + this.email, ); - } else { - // Online only - const request = new SecretVerificationRequest(); - const serverKeyHash = await this.cryptoService.hashMasterKey( - this.masterPassword, - masterKey, - HashPurpose.ServerAuthorization, + response = await this.formPromise; + this.enforcedMasterPasswordOptions = MasterPasswordPolicyOptions.fromResponse( + response.policyOptions, ); - request.masterPasswordHash = serverKeyHash; - try { - this.formPromise = this.apiService.postAccountVerifyPassword(request); - const response = await this.formPromise; - this.enforcedMasterPasswordOptions = MasterPasswordPolicyOptions.fromResponse(response); - passwordValid = true; - const localKeyHash = await this.cryptoService.hashMasterKey( - this.masterPassword, - masterKey, - HashPurpose.LocalAuthorization, - ); - await this.masterPasswordService.setMasterKeyHash(localKeyHash, userId); - } catch (e) { - this.logService.error(e); - } finally { - this.formPromise = null; - } + passwordValid = true; + } catch (e) { + this.logService.error(e); + } finally { + this.formPromise = null; } if (!passwordValid) { @@ -274,8 +256,9 @@ export class LockComponent implements OnInit, OnDestroy { return; } - const userKey = await this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey); - await this.masterPasswordService.setMasterKey(masterKey, userId); + const userKey = await this.masterPasswordService.decryptUserKeyWithMasterKey( + response.masterKey, + ); await this.setUserKeyAndContinue(userKey, true); } diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index e364b290715..e06b2788761 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -875,7 +875,6 @@ const safeProviders: SafeProvider[] = [ provide: UserVerificationServiceAbstraction, useClass: UserVerificationService, deps: [ - StateServiceAbstraction, CryptoServiceAbstraction, AccountServiceAbstraction, InternalMasterPasswordServiceAbstraction, diff --git a/libs/common/src/abstractions/api.service.ts b/libs/common/src/abstractions/api.service.ts index ed43849d62b..aa25849e376 100644 --- a/libs/common/src/abstractions/api.service.ts +++ b/libs/common/src/abstractions/api.service.ts @@ -61,7 +61,6 @@ import { IdentityCaptchaResponse } from "../auth/models/response/identity-captch import { IdentityTokenResponse } from "../auth/models/response/identity-token.response"; import { IdentityTwoFactorResponse } from "../auth/models/response/identity-two-factor.response"; import { KeyConnectorUserKeyResponse } from "../auth/models/response/key-connector-user-key.response"; -import { MasterPasswordPolicyResponse } from "../auth/models/response/master-password-policy.response"; import { PreloginResponse } from "../auth/models/response/prelogin.response"; import { RegisterResponse } from "../auth/models/response/register.response"; import { SsoPreValidateResponse } from "../auth/models/response/sso-pre-validate.response"; @@ -175,9 +174,6 @@ export abstract class ApiService { postAccountKeys: (request: KeysRequest) => Promise; postAccountVerifyEmail: () => Promise; postAccountVerifyEmailToken: (request: VerifyEmailRequest) => Promise; - postAccountVerifyPassword: ( - request: SecretVerificationRequest, - ) => Promise; postAccountRecoverDelete: (request: DeleteRecoverRequest) => Promise; postAccountRecoverDeleteToken: (request: VerifyDeleteRecoverRequest) => Promise; postAccountKdf: (request: KdfRequest) => Promise; diff --git a/libs/common/src/auth/abstractions/user-verification/user-verification-api.service.abstraction.ts b/libs/common/src/auth/abstractions/user-verification/user-verification-api.service.abstraction.ts index b861ce44712..ae17abe823e 100644 --- a/libs/common/src/auth/abstractions/user-verification/user-verification-api.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/user-verification/user-verification-api.service.abstraction.ts @@ -1,6 +1,11 @@ +import { SecretVerificationRequest } from "../../models/request/secret-verification.request"; import { VerifyOTPRequest } from "../../models/request/verify-otp.request"; +import { MasterPasswordPolicyResponse } from "../../models/response/master-password-policy.response"; export abstract class UserVerificationApiServiceAbstraction { postAccountVerifyOTP: (request: VerifyOTPRequest) => Promise; postAccountRequestOTP: () => Promise; + postAccountVerifyPassword: ( + request: SecretVerificationRequest, + ) => Promise; } diff --git a/libs/common/src/auth/abstractions/user-verification/user-verification.service.abstraction.ts b/libs/common/src/auth/abstractions/user-verification/user-verification.service.abstraction.ts index 11fe537919e..fd04b2e2c59 100644 --- a/libs/common/src/auth/abstractions/user-verification/user-verification.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/user-verification/user-verification.service.abstraction.ts @@ -1,19 +1,53 @@ +import { UserId } from "../../../types/guid"; import { SecretVerificationRequest } from "../../models/request/secret-verification.request"; import { UserVerificationOptions } from "../../types/user-verification-options"; -import { Verification } from "../../types/verification"; +import { + MasterPasswordVerification, + MasterPasswordVerificationResponse, + Verification, +} from "../../types/verification"; export abstract class UserVerificationService { + /** + * Returns the available verification options for the user, can be + * restricted to a specific type of verification. + * @param verificationType Type of verification to restrict the options to + * @returns Available verification options for the user + */ + getAvailableVerificationOptions: ( + verificationType: keyof UserVerificationOptions, + ) => Promise; + /** + * Create a new request model to be used for server-side verification + * @param verification User-supplied verification data (Master Password or OTP) + * @param requestClass The request model to create + * @param alreadyHashed Whether the master password is already hashed + * @throws Error if the verification data is invalid + */ buildRequest: ( verification: Verification, requestClass?: new () => T, alreadyHashed?: boolean, ) => Promise; + /** + * Verifies the user using the provided verification data. + * PIN or biometrics are verified client-side. + * OTP is sent to the server for verification (with no other data) + * Master Password verifies client-side first if there is a MP hash, or server-side if not. + * @param verification User-supplied verification data (OTP, MP, PIN, or biometrics) + * @throws Error if the verification data is invalid or the verification fails + */ verifyUser: (verification: Verification) => Promise; + /** + * Request a one-time password (OTP) to be sent to the user's email + */ requestOTP: () => Promise; /** - * Check if user has master password or only uses passwordless technologies to log in + * Check if user has master password or can only use passwordless technologies to log in + * Note: This only checks the server, not the local state * @param userId The user id to check. If not provided, the current user is used * @returns True if the user has a master password + * @deprecated Use UserDecryptionOptionsService.hasMasterPassword$ instead */ hasMasterPassword: (userId?: string) => Promise; /** @@ -22,8 +56,19 @@ export abstract class UserVerificationService { * @returns True if the user has a master password and has used it in the current session */ hasMasterPasswordAndMasterKeyHash: (userId?: string) => Promise; - - getAvailableVerificationOptions: ( - verificationType: keyof UserVerificationOptions, - ) => Promise; + /** + * Verifies the user using the provided master password. + * Attempts to verify client-side first, then server-side if necessary. + * IMPORTANT: Will throw an error if the master password is invalid. + * @param verification Master Password verification data + * @param userId The user to verify + * @param email The user's email + * @throws Error if the master password is invalid + * @returns An object containing the master key, and master password policy options if verified on server. + */ + verifyUserByMasterPassword: ( + verification: MasterPasswordVerification, + userId: UserId, + email: string, + ) => Promise; } diff --git a/libs/common/src/auth/services/user-verification/user-verification-api.service.ts b/libs/common/src/auth/services/user-verification/user-verification-api.service.ts index 0f0eb16e92a..854aaed1197 100644 --- a/libs/common/src/auth/services/user-verification/user-verification-api.service.ts +++ b/libs/common/src/auth/services/user-verification/user-verification-api.service.ts @@ -1,6 +1,8 @@ import { ApiService } from "../../../abstractions/api.service"; import { UserVerificationApiServiceAbstraction } from "../../abstractions/user-verification/user-verification-api.service.abstraction"; +import { SecretVerificationRequest } from "../../models/request/secret-verification.request"; import { VerifyOTPRequest } from "../../models/request/verify-otp.request"; +import { MasterPasswordPolicyResponse } from "../../models/response/master-password-policy.response"; export class UserVerificationApiService implements UserVerificationApiServiceAbstraction { constructor(private apiService: ApiService) {} @@ -11,4 +13,9 @@ export class UserVerificationApiService implements UserVerificationApiServiceAbs async postAccountRequestOTP(): Promise { return this.apiService.send("POST", "/accounts/request-otp", null, true, false); } + postAccountVerifyPassword( + request: SecretVerificationRequest, + ): Promise { + return this.apiService.send("POST", "/accounts/verify-password", request, true, true); + } } diff --git a/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts b/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts new file mode 100644 index 00000000000..653c7a13b33 --- /dev/null +++ b/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts @@ -0,0 +1,418 @@ +import { mock } from "jest-mock-extended"; +import { of } from "rxjs"; + +import { + PinLockType, + PinServiceAbstraction, + UserDecryptionOptions, + UserDecryptionOptionsServiceAbstraction, +} from "@bitwarden/auth/common"; + +import { FakeAccountService, mockAccountServiceWith } from "../../../../spec"; +import { VaultTimeoutSettingsService } from "../../../abstractions/vault-timeout/vault-timeout-settings.service"; +import { CryptoService } from "../../../platform/abstractions/crypto.service"; +import { I18nService } from "../../../platform/abstractions/i18n.service"; +import { LogService } from "../../../platform/abstractions/log.service"; +import { PlatformUtilsService } from "../../../platform/abstractions/platform-utils.service"; +import { HashPurpose } from "../../../platform/enums"; +import { Utils } from "../../../platform/misc/utils"; +import { UserId } from "../../../types/guid"; +import { MasterKey } from "../../../types/key"; +import { KdfConfigService } from "../../abstractions/kdf-config.service"; +import { InternalMasterPasswordServiceAbstraction } from "../../abstractions/master-password.service.abstraction"; +import { UserVerificationApiServiceAbstraction } from "../../abstractions/user-verification/user-verification-api.service.abstraction"; +import { VerificationType } from "../../enums/verification-type"; +import { KdfConfig } from "../../models/domain/kdf-config"; +import { MasterPasswordPolicyResponse } from "../../models/response/master-password-policy.response"; +import { MasterPasswordVerification } from "../../types/verification"; + +import { UserVerificationService } from "./user-verification.service"; + +describe("UserVerificationService", () => { + let sut: UserVerificationService; + + const cryptoService = mock(); + const masterPasswordService = mock(); + const i18nService = mock(); + const userVerificationApiService = mock(); + const userDecryptionOptionsService = mock(); + const pinService = mock(); + const logService = mock(); + const vaultTimeoutSettingsService = mock(); + const platformUtilsService = mock(); + const kdfConfigService = mock(); + + const mockUserId = Utils.newGuid() as UserId; + let accountService: FakeAccountService; + + beforeEach(() => { + jest.clearAllMocks(); + accountService = mockAccountServiceWith(mockUserId); + + sut = new UserVerificationService( + cryptoService, + accountService, + masterPasswordService, + i18nService, + userVerificationApiService, + userDecryptionOptionsService, + pinService, + logService, + vaultTimeoutSettingsService, + platformUtilsService, + kdfConfigService, + ); + }); + + describe("getAvailableVerificationOptions", () => { + describe("client verification type", () => { + it("correctly returns master password availability", async () => { + setMasterPasswordAvailability(true); + setPinAvailability("DISABLED"); + disableBiometricsAvailability(); + + const result = await sut.getAvailableVerificationOptions("client"); + + expect(result).toEqual({ + client: { + masterPassword: true, + pin: false, + biometrics: false, + }, + server: { + masterPassword: false, + otp: false, + }, + }); + }); + + test.each([ + [true, "PERSISTENT"], + [true, "EPHEMERAL"], + [false, "DISABLED"], + ])( + "returns %s for PIN availability when pin lock type is %s", + async (expectedPin: boolean, pinLockType: PinLockType) => { + setMasterPasswordAvailability(false); + setPinAvailability(pinLockType); + disableBiometricsAvailability(); + + const result = await sut.getAvailableVerificationOptions("client"); + + expect(result).toEqual({ + client: { + masterPassword: false, + pin: expectedPin, + biometrics: false, + }, + server: { + masterPassword: false, + otp: false, + }, + }); + }, + ); + + test.each([ + [true, true, true, true], + [true, true, true, false], + [true, true, false, false], + [false, true, false, true], + [false, false, false, false], + [false, false, true, false], + [false, false, false, true], + ])( + "returns %s for biometrics availability when isBiometricLockSet is %s, hasUserKeyStored is %s, and supportsSecureStorage is %s", + async ( + expectedReturn: boolean, + isBiometricsLockSet: boolean, + isBiometricsUserKeyStored: boolean, + platformSupportSecureStorage: boolean, + ) => { + setMasterPasswordAvailability(false); + setPinAvailability("DISABLED"); + vaultTimeoutSettingsService.isBiometricLockSet.mockResolvedValue(isBiometricsLockSet); + cryptoService.hasUserKeyStored.mockResolvedValue(isBiometricsUserKeyStored); + platformUtilsService.supportsSecureStorage.mockReturnValue(platformSupportSecureStorage); + + const result = await sut.getAvailableVerificationOptions("client"); + + expect(result).toEqual({ + client: { + masterPassword: false, + pin: false, + biometrics: expectedReturn, + }, + server: { + masterPassword: false, + otp: false, + }, + }); + }, + ); + }); + + describe("server verification type", () => { + it("correctly returns master password availability", async () => { + userDecryptionOptionsService.userDecryptionOptionsById$.mockReturnValue( + of({ + hasMasterPassword: true, + } as UserDecryptionOptions), + ); + + const result = await sut.getAvailableVerificationOptions("server"); + + expect(result).toEqual({ + client: { + masterPassword: false, + pin: false, + biometrics: false, + }, + server: { + masterPassword: true, + otp: false, + }, + }); + }); + + it("correctly returns OTP availability", async () => { + userDecryptionOptionsService.userDecryptionOptionsById$.mockReturnValue( + of({ + hasMasterPassword: false, + } as UserDecryptionOptions), + ); + + const result = await sut.getAvailableVerificationOptions("server"); + + expect(result).toEqual({ + client: { + masterPassword: false, + pin: false, + biometrics: false, + }, + server: { + masterPassword: false, + otp: true, + }, + }); + }); + }); + }); + + describe("verifyUserByMasterPassword", () => { + beforeAll(() => { + i18nService.t.calledWith("invalidMasterPassword").mockReturnValue("Invalid master password"); + + kdfConfigService.getKdfConfig.mockResolvedValue("kdfConfig" as unknown as KdfConfig); + masterPasswordService.masterKey$.mockReturnValue(of("masterKey" as unknown as MasterKey)); + cryptoService.hashMasterKey + .calledWith("password", "masterKey" as unknown as MasterKey, HashPurpose.LocalAuthorization) + .mockResolvedValue("localHash"); + }); + + describe("client-side verification", () => { + beforeEach(() => { + setMasterPasswordAvailability(true); + }); + + it("returns if verification is successful", async () => { + cryptoService.compareAndUpdateKeyHash.mockResolvedValueOnce(true); + + const result = await sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + mockUserId, + "email", + ); + + expect(cryptoService.compareAndUpdateKeyHash).toHaveBeenCalled(); + expect(masterPasswordService.setMasterKeyHash).toHaveBeenCalledWith( + "localHash", + mockUserId, + ); + expect(masterPasswordService.setMasterKey).toHaveBeenCalledWith("masterKey", mockUserId); + expect(result).toEqual({ + policyOptions: null, + masterKey: "masterKey", + }); + }); + + it("throws if verification fails", async () => { + cryptoService.compareAndUpdateKeyHash.mockResolvedValueOnce(false); + + await expect( + sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + mockUserId, + "email", + ), + ).rejects.toThrow("Invalid master password"); + + expect(cryptoService.compareAndUpdateKeyHash).toHaveBeenCalled(); + expect(masterPasswordService.setMasterKeyHash).not.toHaveBeenCalledWith(); + expect(masterPasswordService.setMasterKey).not.toHaveBeenCalledWith(); + }); + }); + + describe("server-side verification", () => { + beforeEach(() => { + setMasterPasswordAvailability(false); + }); + + it("returns if verification is successful", async () => { + cryptoService.hashMasterKey + .calledWith( + "password", + "masterKey" as unknown as MasterKey, + HashPurpose.ServerAuthorization, + ) + .mockResolvedValueOnce("serverHash"); + userVerificationApiService.postAccountVerifyPassword.mockResolvedValueOnce( + "MasterPasswordPolicyOptions" as unknown as MasterPasswordPolicyResponse, + ); + + const result = await sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + mockUserId, + "email", + ); + + expect(cryptoService.compareAndUpdateKeyHash).not.toHaveBeenCalled(); + expect(masterPasswordService.setMasterKeyHash).toHaveBeenCalledWith( + "localHash", + mockUserId, + ); + expect(masterPasswordService.setMasterKey).toHaveBeenCalledWith("masterKey", mockUserId); + expect(result).toEqual({ + policyOptions: "MasterPasswordPolicyOptions", + masterKey: "masterKey", + }); + }); + + it("throws if verification fails", async () => { + cryptoService.hashMasterKey + .calledWith( + "password", + "masterKey" as unknown as MasterKey, + HashPurpose.ServerAuthorization, + ) + .mockResolvedValueOnce("serverHash"); + userVerificationApiService.postAccountVerifyPassword.mockRejectedValueOnce(new Error()); + + await expect( + sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + mockUserId, + "email", + ), + ).rejects.toThrow("Invalid master password"); + + expect(cryptoService.compareAndUpdateKeyHash).not.toHaveBeenCalled(); + expect(masterPasswordService.setMasterKeyHash).not.toHaveBeenCalledWith(); + expect(masterPasswordService.setMasterKey).not.toHaveBeenCalledWith(); + }); + }); + + describe("error handling", () => { + it("throws if any of the parameters are nullish", async () => { + await expect( + sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: null, + } as MasterPasswordVerification, + mockUserId, + "email", + ), + ).rejects.toThrow( + "Master Password is required. Cannot verify user without a master password.", + ); + + await expect( + sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + null, + "email", + ), + ).rejects.toThrow("User ID is required. Cannot verify user by master password."); + + await expect( + sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + mockUserId, + null, + ), + ).rejects.toThrow("Email is required. Cannot verify user by master password."); + }); + + it("throws if kdf config is not available", async () => { + kdfConfigService.getKdfConfig.mockResolvedValueOnce(null); + + await expect( + sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + mockUserId, + "email", + ), + ).rejects.toThrow("KDF config is required. Cannot verify user by master password."); + }); + + it("throws if master key cannot be created", async () => { + kdfConfigService.getKdfConfig.mockResolvedValueOnce("kdfConfig" as unknown as KdfConfig); + masterPasswordService.masterKey$.mockReturnValueOnce(of(null)); + cryptoService.makeMasterKey.mockResolvedValueOnce(null); + + await expect( + sut.verifyUserByMasterPassword( + { + type: VerificationType.MasterPassword, + secret: "password", + } as MasterPasswordVerification, + mockUserId, + "email", + ), + ).rejects.toThrow("Master key could not be created to verify the master password."); + }); + }); + }); + + // Helpers + function setMasterPasswordAvailability(hasMasterPassword: boolean) { + userDecryptionOptionsService.userDecryptionOptionsById$.mockReturnValue( + of({ + hasMasterPassword: hasMasterPassword, + } as UserDecryptionOptions), + ); + masterPasswordService.masterKeyHash$.mockReturnValue( + of(hasMasterPassword ? "masterKeyHash" : null), + ); + } + + function setPinAvailability(type: PinLockType) { + pinService.getPinLockType.mockResolvedValue(type); + } + + function disableBiometricsAvailability() { + vaultTimeoutSettingsService.isBiometricLockSet.mockResolvedValue(false); + } +}); diff --git a/libs/common/src/auth/services/user-verification/user-verification.service.ts b/libs/common/src/auth/services/user-verification/user-verification.service.ts index 85640519ec3..50fe7b3add5 100644 --- a/libs/common/src/auth/services/user-verification/user-verification.service.ts +++ b/libs/common/src/auth/services/user-verification/user-verification.service.ts @@ -8,7 +8,7 @@ import { CryptoService } from "../../../platform/abstractions/crypto.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { LogService } from "../../../platform/abstractions/log.service"; import { PlatformUtilsService } from "../../../platform/abstractions/platform-utils.service"; -import { StateService } from "../../../platform/abstractions/state.service"; +import { HashPurpose } from "../../../platform/enums"; import { KeySuffixOptions } from "../../../platform/enums/key-suffix-options.enum"; import { UserId } from "../../../types/guid"; import { UserKey } from "../../../types/key"; @@ -20,9 +20,11 @@ import { UserVerificationService as UserVerificationServiceAbstraction } from ". import { VerificationType } from "../../enums/verification-type"; import { SecretVerificationRequest } from "../../models/request/secret-verification.request"; import { VerifyOTPRequest } from "../../models/request/verify-otp.request"; +import { MasterPasswordPolicyResponse } from "../../models/response/master-password-policy.response"; import { UserVerificationOptions } from "../../types/user-verification-options"; import { MasterPasswordVerification, + MasterPasswordVerificationResponse, OtpVerification, PinVerification, ServerSideVerification, @@ -37,7 +39,6 @@ import { */ export class UserVerificationService implements UserVerificationServiceAbstraction { constructor( - private stateService: StateService, private cryptoService: CryptoService, private accountService: AccountService, private masterPasswordService: InternalMasterPasswordServiceAbstraction, @@ -54,14 +55,14 @@ export class UserVerificationService implements UserVerificationServiceAbstracti async getAvailableVerificationOptions( verificationType: keyof UserVerificationOptions, ): Promise { + const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; if (verificationType === "client") { - const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; const [userHasMasterPassword, pinLockType, biometricsLockSet, biometricsUserKeyStored] = await Promise.all([ - this.hasMasterPasswordAndMasterKeyHash(), + this.hasMasterPasswordAndMasterKeyHash(userId), this.pinService.getPinLockType(userId), - this.vaultTimeoutSettingsService.isBiometricLockSet(), - this.cryptoService.hasUserKeyStored(KeySuffixOptions.Biometric), + this.vaultTimeoutSettingsService.isBiometricLockSet(userId), + this.cryptoService.hasUserKeyStored(KeySuffixOptions.Biometric, userId), ]); // note: we do not need to check this.platformUtilsService.supportsBiometric() because @@ -83,7 +84,7 @@ export class UserVerificationService implements UserVerificationServiceAbstracti } else { // server // Don't check if have MP hash locally, because we are going to send the secret to the server to be verified. - const userHasMasterPassword = await this.hasMasterPassword(); + const userHasMasterPassword = await this.hasMasterPassword(userId); return { client: { @@ -96,12 +97,6 @@ export class UserVerificationService implements UserVerificationServiceAbstracti } } - /** - * Create a new request model to be used for server-side verification - * @param verification User-supplied verification data (Master Password or OTP) - * @param requestClass The request model to create - * @param alreadyHashed Whether the master password is already hashed - */ async buildRequest( verification: ServerSideVerification, requestClass?: new () => T, @@ -134,11 +129,6 @@ export class UserVerificationService implements UserVerificationServiceAbstracti return request; } - /** - * Used to verify Master Password, PIN, or biometrics client-side, or send the OTP to the server for verification (with no other data) - * Generally used for client-side verification only. - * @param verification User-supplied verification data (OTP, MP, PIN, or biometrics) - */ async verifyUser(verification: Verification): Promise { if (verification == null) { throw new Error("Verification is required."); @@ -156,7 +146,8 @@ export class UserVerificationService implements UserVerificationServiceAbstracti case VerificationType.OTP: return this.verifyUserByOTP(verification); case VerificationType.MasterPassword: - return this.verifyUserByMasterPassword(verification, userId, email); + await this.verifyUserByMasterPassword(verification, userId, email); + return true; case VerificationType.PIN: return this.verifyUserByPIN(verification, userId); case VerificationType.Biometrics: @@ -179,33 +170,70 @@ export class UserVerificationService implements UserVerificationServiceAbstracti return true; } - private async verifyUserByMasterPassword( + async verifyUserByMasterPassword( verification: MasterPasswordVerification, userId: UserId, email: string, - ): Promise { + ): Promise { + if (!verification.secret) { + throw new Error("Master Password is required. Cannot verify user without a master password."); + } if (!userId) { throw new Error("User ID is required. Cannot verify user by master password."); } + if (!email) { + throw new Error("Email is required. Cannot verify user by master password."); + } + + const kdfConfig = await this.kdfConfigService.getKdfConfig(); + if (!kdfConfig) { + throw new Error("KDF config is required. Cannot verify user by master password."); + } let masterKey = await firstValueFrom(this.masterPasswordService.masterKey$(userId)); if (!masterKey) { - masterKey = await this.cryptoService.makeMasterKey( - verification.secret, - email, - await this.kdfConfigService.getKdfConfig(), - ); + masterKey = await this.cryptoService.makeMasterKey(verification.secret, email, kdfConfig); } - const passwordValid = await this.cryptoService.compareAndUpdateKeyHash( + + if (!masterKey) { + throw new Error("Master key could not be created to verify the master password."); + } + + let policyOptions: MasterPasswordPolicyResponse | null; + // Client-side verification + if (await this.hasMasterPasswordAndMasterKeyHash(userId)) { + const passwordValid = await this.cryptoService.compareAndUpdateKeyHash( + verification.secret, + masterKey, + ); + if (!passwordValid) { + throw new Error(this.i18nService.t("invalidMasterPassword")); + } + policyOptions = null; + } else { + // Server-side verification + const request = new SecretVerificationRequest(); + const serverKeyHash = await this.cryptoService.hashMasterKey( + verification.secret, + masterKey, + HashPurpose.ServerAuthorization, + ); + request.masterPasswordHash = serverKeyHash; + try { + policyOptions = await this.userVerificationApiService.postAccountVerifyPassword(request); + } catch (e) { + throw new Error(this.i18nService.t("invalidMasterPassword")); + } + } + + const localKeyHash = await this.cryptoService.hashMasterKey( verification.secret, masterKey, + HashPurpose.LocalAuthorization, ); - if (!passwordValid) { - throw new Error(this.i18nService.t("invalidMasterPassword")); - } - // TODO: we should re-evaluate later on if user verification should have the side effect of modifying state. Probably not. + await this.masterPasswordService.setMasterKeyHash(localKeyHash, userId); await this.masterPasswordService.setMasterKey(masterKey, userId); - return true; + return { policyOptions, masterKey }; } private async verifyUserByPIN(verification: PinVerification, userId: UserId): Promise { @@ -236,13 +264,6 @@ export class UserVerificationService implements UserVerificationServiceAbstracti await this.userVerificationApiService.postAccountRequestOTP(); } - /** - * Check if user has master password or can only use passwordless technologies to log in - * Note: This only checks the server, not the local state - * @param userId The user id to check. If not provided, the current user is used - * @returns True if the user has a master password - * @deprecated Use UserDecryptionOptionsService.hasMasterPassword$ instead - */ async hasMasterPassword(userId?: string): Promise { if (userId) { const decryptionOptions = await firstValueFrom( diff --git a/libs/common/src/auth/types/verification.ts b/libs/common/src/auth/types/verification.ts index 8bb0813be7c..2dddd5fb914 100644 --- a/libs/common/src/auth/types/verification.ts +++ b/libs/common/src/auth/types/verification.ts @@ -1,4 +1,6 @@ +import { MasterKey } from "../../types/key"; import { VerificationType } from "../enums/verification-type"; +import { MasterPasswordPolicyResponse } from "../models/response/master-password-policy.response"; export type OtpVerification = { type: VerificationType.OTP; secret: string }; export type MasterPasswordVerification = { type: VerificationType.MasterPassword; secret: string }; @@ -17,3 +19,8 @@ export function verificationHasSecret( } export type ServerSideVerification = OtpVerification | MasterPasswordVerification; + +export type MasterPasswordVerificationResponse = { + masterKey: MasterKey; + policyOptions: MasterPasswordPolicyResponse; +}; diff --git a/libs/common/src/services/api.service.ts b/libs/common/src/services/api.service.ts index 40ff5e7bef3..48ba6433916 100644 --- a/libs/common/src/services/api.service.ts +++ b/libs/common/src/services/api.service.ts @@ -70,7 +70,6 @@ import { IdentityCaptchaResponse } from "../auth/models/response/identity-captch import { IdentityTokenResponse } from "../auth/models/response/identity-token.response"; import { IdentityTwoFactorResponse } from "../auth/models/response/identity-two-factor.response"; import { KeyConnectorUserKeyResponse } from "../auth/models/response/key-connector-user-key.response"; -import { MasterPasswordPolicyResponse } from "../auth/models/response/master-password-policy.response"; import { PreloginResponse } from "../auth/models/response/prelogin.response"; import { RegisterResponse } from "../auth/models/response/register.response"; import { SsoPreValidateResponse } from "../auth/models/response/sso-pre-validate.response"; @@ -424,12 +423,6 @@ export class ApiService implements ApiServiceAbstraction { return this.send("POST", "/accounts/verify-email-token", request, false, false); } - postAccountVerifyPassword( - request: SecretVerificationRequest, - ): Promise { - return this.send("POST", "/accounts/verify-password", request, true, true); - } - postAccountRecoverDelete(request: DeleteRecoverRequest): Promise { return this.send("POST", "/accounts/delete-recover", request, false, false); } From 0dd476588df776d4114baf53ef2b51f9dd11d888 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:17:54 -0400 Subject: [PATCH 23/29] PM-8886 - SsoComponent - fix missing form validation (#9665) --- apps/web/src/app/auth/sso.component.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/web/src/app/auth/sso.component.ts b/apps/web/src/app/auth/sso.component.ts index 2b8f20ed424..731cade3746 100644 --- a/apps/web/src/app/auth/sso.component.ts +++ b/apps/web/src/app/auth/sso.component.ts @@ -141,6 +141,10 @@ export class SsoComponent extends BaseSsoComponent { } submit = async () => { + if (this.formGroup.invalid) { + return; + } + this.identifier = this.identifierFormControl.value; await this.ssoLoginService.setOrganizationSsoIdentifier(this.identifier); if (this.clientId === "browser") { From afe9a1768a456de36486373da610febcc5ac638a Mon Sep 17 00:00:00 2001 From: Robyn MacCallum Date: Fri, 14 Jun 2024 16:54:52 -0400 Subject: [PATCH 24/29] [SM-1305] Add Kubernetes and Rust to the integrations page (#9611) * Add Kubernetes and Rust to the integrations page * Fix integrations page tests --- .../integrations/kubernetes.svg | 11 +++++ .../secrets-manager/sdks/rust-white.svg | 48 +++++++++++++++++++ .../src/images/secrets-manager/sdks/rust.svg | 48 +++++++++++++++++++ apps/web/src/locales/en/messages.json | 6 +++ .../integrations.component.spec.ts | 4 +- .../integrations/integrations.component.ts | 16 +++++++ 6 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 apps/web/src/images/secrets-manager/integrations/kubernetes.svg create mode 100644 apps/web/src/images/secrets-manager/sdks/rust-white.svg create mode 100644 apps/web/src/images/secrets-manager/sdks/rust.svg diff --git a/apps/web/src/images/secrets-manager/integrations/kubernetes.svg b/apps/web/src/images/secrets-manager/integrations/kubernetes.svg new file mode 100644 index 00000000000..00ad2b72b68 --- /dev/null +++ b/apps/web/src/images/secrets-manager/integrations/kubernetes.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/web/src/images/secrets-manager/sdks/rust-white.svg b/apps/web/src/images/secrets-manager/sdks/rust-white.svg new file mode 100644 index 00000000000..ce3f3f91043 --- /dev/null +++ b/apps/web/src/images/secrets-manager/sdks/rust-white.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/images/secrets-manager/sdks/rust.svg b/apps/web/src/images/secrets-manager/sdks/rust.svg new file mode 100644 index 00000000000..a099c1519c8 --- /dev/null +++ b/apps/web/src/images/secrets-manager/sdks/rust.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 5b9e7c9c829..1d0e882b179 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8180,12 +8180,18 @@ "setUpGithubActions": { "message": "Set up Github Actions" }, + "setUpKubernetes": { + "message": "Set up Kubernetes" + }, "setUpGitlabCICD": { "message": "Set up GitLab CI/CD" }, "setUpAnsible": { "message": "Set up Ansible" }, + "rustSDKRepo": { + "message": "View Rust repository" + }, "cSharpSDKRepo": { "message": "View C# repository" }, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts index 10fbaa1f3fb..6c8ea28bc2f 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts @@ -68,10 +68,10 @@ describe("IntegrationsComponent", () => { (integrationList.componentInstance as IntegrationGridComponent).integrations.map( (i) => i.name, ), - ).toEqual(["GitHub Actions", "GitLab CI/CD", "Ansible"]); + ).toEqual(["GitHub Actions", "GitLab CI/CD", "Ansible", "Kubernetes Operator"]); expect( (sdkList.componentInstance as IntegrationGridComponent).integrations.map((i) => i.name), - ).toEqual(["C#", "C++", "Go", "Java", "JS WebAssembly", "php", "Python", "Ruby"]); + ).toEqual(["Rust", "C#", "C++", "Go", "Java", "JS WebAssembly", "php", "Python", "Ruby"]); }); }); diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts index f11048b6a30..9e846d45034 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts @@ -14,6 +14,14 @@ export class IntegrationsComponent { constructor(i18nService: I18nService) { this.integrationsAndSdks = [ + { + name: "Rust", + linkText: i18nService.t("rustSDKRepo"), + linkURL: "https://github.com/bitwarden/sdk", + image: "../../../../../../../images/secrets-manager/sdks/rust.svg", + imageDarkMode: "../../../../../../../images/secrets-manager/sdks/rust-white.svg", + type: IntegrationType.SDK, + }, { name: "GitHub Actions", linkText: i18nService.t("setUpGithubActions"), @@ -94,6 +102,14 @@ export class IntegrationsComponent { image: "../../../../../../../images/secrets-manager/sdks/ruby.png", type: IntegrationType.SDK, }, + { + name: "Kubernetes Operator", + linkText: i18nService.t("setUpKubernetes"), + linkURL: "https://bitwarden.com/help/secrets-manager-kubernetes-operator/", + image: "../../../../../../../images/secrets-manager/integrations/kubernetes.svg", + type: IntegrationType.Integration, + newBadgeExpiration: "2024-8-12", + }, ]; } From b15cac627ff53415eb31ad6d9441ff5ad3d8c106 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Sat, 15 Jun 2024 11:10:00 -0400 Subject: [PATCH 25/29] Auth/ Fix web route data configuration issues for SSO comp and Accept Emergency comp (#9671) --- apps/web/src/app/oss-routing.module.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 7dafb9ab6a1..810cba453b1 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -222,14 +222,14 @@ const routes: Routes = [ { path: "sso", canActivate: [unauthGuardFn()], + data: { + pageTitle: "enterpriseSingleSignOn", + titleId: "enterpriseSingleSignOn", + } satisfies DataProperties & AnonLayoutWrapperData, children: [ { path: "", component: SsoComponent, - data: { - pageTitle: "enterpriseSingleSignOn", - titleId: "enterpriseSingleSignOn", - } satisfies DataProperties & AnonLayoutWrapperData, }, { path: "", @@ -286,14 +286,14 @@ const routes: Routes = [ { path: "accept-emergency", canActivate: [deepLinkGuard()], + data: { + pageTitle: "emergencyAccess", + titleId: "acceptEmergency", + doNotSaveUrl: false, + } satisfies DataProperties & AnonLayoutWrapperData, children: [ { path: "", - data: { - pageTitle: "emergencyAccess", - titleId: "acceptEmergency", - doNotSaveUrl: false, - } satisfies DataProperties & AnonLayoutWrapperData, loadComponent: () => import("./auth/emergency-access/accept/accept-emergency.component").then( (mod) => mod.AcceptEmergencyComponent, From aab9b0e73c56bda8873e8138ad8c8e2f01783041 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 16 Jun 2024 07:18:57 +0000 Subject: [PATCH 26/29] Autosync the updated translations (#9641) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 51 +++-- apps/browser/src/_locales/az/messages.json | 55 +++--- apps/browser/src/_locales/be/messages.json | 51 +++-- apps/browser/src/_locales/bg/messages.json | 55 +++--- apps/browser/src/_locales/bn/messages.json | 51 +++-- apps/browser/src/_locales/bs/messages.json | 51 +++-- apps/browser/src/_locales/ca/messages.json | 51 +++-- apps/browser/src/_locales/cs/messages.json | 55 +++--- apps/browser/src/_locales/cy/messages.json | 51 +++-- apps/browser/src/_locales/da/messages.json | 51 +++-- apps/browser/src/_locales/de/messages.json | 67 ++++--- apps/browser/src/_locales/el/messages.json | 51 +++-- apps/browser/src/_locales/en_GB/messages.json | 51 +++-- apps/browser/src/_locales/en_IN/messages.json | 55 +++--- apps/browser/src/_locales/es/messages.json | 55 +++--- apps/browser/src/_locales/et/messages.json | 51 +++-- apps/browser/src/_locales/eu/messages.json | 51 +++-- apps/browser/src/_locales/fa/messages.json | 51 +++-- apps/browser/src/_locales/fi/messages.json | 107 +++++----- apps/browser/src/_locales/fil/messages.json | 51 +++-- apps/browser/src/_locales/fr/messages.json | 51 +++-- apps/browser/src/_locales/gl/messages.json | 51 +++-- apps/browser/src/_locales/he/messages.json | 55 +++--- apps/browser/src/_locales/hi/messages.json | 51 +++-- apps/browser/src/_locales/hr/messages.json | 51 +++-- apps/browser/src/_locales/hu/messages.json | 55 +++--- apps/browser/src/_locales/id/messages.json | 51 +++-- apps/browser/src/_locales/it/messages.json | 51 +++-- apps/browser/src/_locales/ja/messages.json | 51 +++-- apps/browser/src/_locales/ka/messages.json | 51 +++-- apps/browser/src/_locales/km/messages.json | 51 +++-- apps/browser/src/_locales/kn/messages.json | 51 +++-- apps/browser/src/_locales/ko/messages.json | 185 ++++++++++-------- apps/browser/src/_locales/lt/messages.json | 51 +++-- apps/browser/src/_locales/lv/messages.json | 99 +++++----- apps/browser/src/_locales/ml/messages.json | 51 +++-- apps/browser/src/_locales/mr/messages.json | 51 +++-- apps/browser/src/_locales/my/messages.json | 51 +++-- apps/browser/src/_locales/nb/messages.json | 51 +++-- apps/browser/src/_locales/ne/messages.json | 51 +++-- apps/browser/src/_locales/nl/messages.json | 51 +++-- apps/browser/src/_locales/nn/messages.json | 51 +++-- apps/browser/src/_locales/or/messages.json | 51 +++-- apps/browser/src/_locales/pl/messages.json | 51 +++-- apps/browser/src/_locales/pt_BR/messages.json | 51 +++-- apps/browser/src/_locales/pt_PT/messages.json | 51 +++-- apps/browser/src/_locales/ro/messages.json | 51 +++-- apps/browser/src/_locales/ru/messages.json | 55 +++--- apps/browser/src/_locales/si/messages.json | 51 +++-- apps/browser/src/_locales/sk/messages.json | 55 +++--- apps/browser/src/_locales/sl/messages.json | 51 +++-- apps/browser/src/_locales/sr/messages.json | 51 +++-- apps/browser/src/_locales/sv/messages.json | 51 +++-- apps/browser/src/_locales/te/messages.json | 51 +++-- apps/browser/src/_locales/th/messages.json | 51 +++-- apps/browser/src/_locales/tr/messages.json | 51 +++-- apps/browser/src/_locales/uk/messages.json | 55 +++--- apps/browser/src/_locales/vi/messages.json | 51 +++-- apps/browser/src/_locales/zh_CN/messages.json | 101 +++++----- apps/browser/src/_locales/zh_TW/messages.json | 51 +++-- apps/browser/store/locales/ko/copy.resx | 2 +- apps/browser/store/locales/uk/copy.resx | 48 ++--- 62 files changed, 2057 insertions(+), 1397 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index b689a7e3fc0..4232a0bbc81 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "الهوية" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "سجل كلمة المرور" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 4ded914a439..d109aa0e79c 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -393,10 +393,10 @@ "message": "Sevimlilərdən sil" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Element sevimlilərə əlavə edildi" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Element sevimlilərdən çıxarıldı" }, "notes": { "message": "Notlar" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Kimlik" }, + "newItemHeader": { + "message": "Yeni $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "$TYPE$ - düzəliş et", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Parol tarixçəsi" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Filtrləri təmizləyin və ya başqa bir axtarış terminini sınayın" }, - "copyInfoLabel": { - "message": "$ITEMNAME$ elementlərini kopyala", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Məlumatları kopyala - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "$ITEMNAME$ notunu kopyala", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Notu kopyala - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Avto-doldur - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Kopyalanacaq dəyər yoxdur" + }, "assignCollections": { "message": "Kolleksiyaları təyin et" }, diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 22aa6e1fa33..e8d3e048643 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Пасведчанне" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Гісторыя пароляў" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index c5cf062b344..9071ac7cad1 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -393,10 +393,10 @@ "message": "Изваждане от любими" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Елементът е добавен към любимите" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Елементът е премахнат от любимите" }, "notes": { "message": "Бележки" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Самоличност" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Редактиране на $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Хронология на паролата" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Изчистете филтрите или опитайте да търсите нещо друго" }, - "copyInfoLabel": { - "message": "Копиране на информацията, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Копиране на информацията – $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Копиране на бележката, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Копиране на бележката – $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Авт. попълване – $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Няма стойности за копиране" + }, "assignCollections": { "message": "Свързване на колекции" }, diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 3ddf7a32bde..6bc79efd4d4 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "পরিচয়" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "পাসওয়ার্ড ইতিহাস" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index f8d275245ea..a3cc4ea4962 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index aee61f4b1ad..40e9ca8844d 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitat" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Historial de les contrasenyes" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index a865a1a9472..4ebf0d3901f 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -393,10 +393,10 @@ "message": "Unfavorite" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Položka byla přidána do oblíbených" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Položka byla odebrána z oblíbených" }, "notes": { "message": "Poznámky" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identita" }, + "newItemHeader": { + "message": "Nové $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Upravit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Historie hesel" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Vymažte filtry nebo zkuste jiný hledaný výraz" }, - "copyInfoLabel": { - "message": "Kopírovat informace, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Kopírovat informace - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Kopírovat poznámku, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Kopírovat poznámku - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Automatické vyplnění - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Žádné hodnoty ke zkopírování" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index f90120a0823..e43d33ceb46 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Hunaniaeth" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Hanes cyfrineiriau" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 7b5b7ec2e29..f3248376fd6 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitet" }, + "newItemHeader": { + "message": "Ny $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Redigér $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Adgangskodehistorik" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Ryd filtre eller prøv med et andet søgeord" }, - "copyInfoLabel": { - "message": "Kopiér info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Kopiér info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Kopiér notat, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Kopiér notat - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Autoudfyld - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Ingen værdier at kopiere" + }, "assignCollections": { "message": "Tildel samlinger" }, diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index dddc6fc9762..e38a307df25 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -390,13 +390,13 @@ "message": "Favoriten" }, "unfavorite": { - "message": "Unfavorite" + "message": "Aus Favoriten entfernen" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Eintrag zu Favoriten hinzugefügt" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Eintrag aus Favoriten entfernt" }, "notes": { "message": "Notizen" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identität" }, + "newItemHeader": { + "message": "Neue $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "$TYPE$ bearbeiten", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Passwortverlauf" }, @@ -3305,18 +3323,8 @@ "clearFiltersOrTryAnother": { "message": "Entferne die Filter oder versuche einen anderen Suchbegriff" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Information kopieren - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -3325,18 +3333,8 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Notiz kopieren - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -3346,7 +3344,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Weitere Optionen, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3356,7 +3354,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Weitere Optionen - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3366,7 +3364,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Eintrag anzeigen - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-Ausfüllen - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Keine Werte zum Kopieren" + }, "assignCollections": { "message": "Sammlungen zuweisen" }, diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 1f97b3623c2..9c9a49ee1cb 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Ταυτότητα" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Ιστορικό Κωδικού" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index c7465f915e8..c73f26a284d 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 0e3efdd15f1..6a301b57e48 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -393,10 +393,10 @@ "message": "Unfavourite" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Item added to favourites" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Item removed from favourites" }, "notes": { "message": "Notes" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index af10b5719aa..64b8fdcedce 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -393,10 +393,10 @@ "message": "Eliminar favorito" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Elemento añadido a favoritos" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Elemento eliminado de favoritos" }, "notes": { "message": "Notas" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identidad" }, + "newItemHeader": { + "message": "Nuevo $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Editar $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Historial de contraseñas" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Limpia los filtros o prueba otro término de búsqueda" }, - "copyInfoLabel": { - "message": "Copiar información, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copiar información - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copiar nota, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copiar nota - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Autocompletar - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No hay valores para copiar" + }, "assignCollections": { "message": "Asignar colecciones" }, diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 6d1a2f7635e..c53e8817c13 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identiteet" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Paroolide ajalugu" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 3ba8820abca..89386601c95 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitatea" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Pasahitz historia" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index b5d383c1364..9694a1a2a78 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "هویت" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "تاریخچه کلمه عبور" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 5cb434f1265..edc2e1e7376 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -390,13 +390,13 @@ "message": "Suosikki" }, "unfavorite": { - "message": "Unfavorite" + "message": "Poista suosikeista" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Kohde lisättiin suosikkeihin" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Kohde poistettiin suosikeista" }, "notes": { "message": "Merkinnät" @@ -420,7 +420,7 @@ "message": "Avaa" }, "launchWebsite": { - "message": "Launch website" + "message": "Avaa verkkosivusto" }, "website": { "message": "Verkkosivusto" @@ -778,7 +778,7 @@ "message": "Avaa" }, "additionalOptions": { - "message": "Lisäasetukset" + "message": "Lisävalinnat" }, "enableContextMenuItem": { "message": "Näytä sisältövalikon valinnat" @@ -845,7 +845,7 @@ "message": "Viennin tyyppi" }, "accountRestricted": { - "message": "Rajoitettu tilille" + "message": "Tiliä on rajoitettu" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { "message": "\"Tiedoston salasana\" ja \"Vahvista tiedoston salasana\" eivät täsmää." @@ -1120,22 +1120,22 @@ "message": "Itse ylläpidetty palvelinympäristö" }, "selfHostedEnvironmentFooter": { - "message": "Määritä omassa palvelinympäristössäsi suoritettavan Bitwarden-asennuksen pääverkkotunnus." + "message": "Määritä omassa palvelinympäristössäsi suoritettavan Bitwarden-asennuksen perusosoite." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Määritä itse ylläpitämäsi Bitwarden-asennuksen perusosoite. Esimerkki: https://bitwarden.yritys.fi." }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Edistynyttä määritystä varten voit syöttää jokaisen palvelun perusosoitteen erikseen." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Sinun on lisättävä joko palvelimen perusosoite tai ainakin yksi mukautettu palvelinympäristö." }, "customEnvironment": { "message": "Mukautettu palvelinympäristö" }, "customEnvironmentFooter": { - "message": "Edistyneille käyttäjille. Voit määrittää jokaiselle palvelulle oman pääverkkotunnuksen." + "message": "Edistyneille käyttäjille. Voit määrittää jokaiselle palvelulle oman perusosoitteen." }, "baseUrl": { "message": "Palvelimen URL" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Henkilöllisyys" }, + "newItemHeader": { + "message": "Uusi $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Muokkaa $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Salasanahistoria" }, @@ -1444,7 +1462,7 @@ "message": "Kokoelmat" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ kokoelmaa", "placeholders": { "count": { "content": "$1", @@ -1682,7 +1700,7 @@ "message": "Automaattitäytä ja tallenna" }, "fillAndSave": { - "message": "Fill and save" + "message": "Täytä ja tallenna" }, "autoFillSuccessAndSavedUri": { "message": "Kohde täytettiin automaattisesti ja URI tallennettiin" @@ -1781,10 +1799,10 @@ "message": "Ok" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Käyttötunnisteen päivitysvirhe" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Päivitystunnistetta tai API-avaimia ei löytynyt. Kokeile kirjautua ulos ja takaisin sisään." }, "desktopSyncVerificationTitle": { "message": "Työpöytäsynkronoinnin vahvistus" @@ -2344,7 +2362,7 @@ } }, "forwaderInvalidToken": { - "message": "Virheellinen $SERVICENAME$ -rajapinnan tunniste", + "message": "Virheellinen $SERVICENAME$ API -tunniste", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2354,7 +2372,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Virheellinen $SERVICENAME$ -rajapinnan tunniste: $ERRORMESSAGE$", + "message": "Virheellinen $SERVICENAME$ API -tunniste: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2368,7 +2386,7 @@ } }, "forwarderNoAccountId": { - "message": "$SERVICENAME$ -palvelun peittämän sähköpostitilin tunnistetta ei saatu.", + "message": "$SERVICENAME$ -palvelun peittämän sähköpostitilin tunnusta ei saatu.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -3305,18 +3323,8 @@ "clearFiltersOrTryAnother": { "message": "Tyhjennä suodattimet tai kokeile toista hakutermiä" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Kopioi tietoja - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -3325,18 +3333,8 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Kopioi muistio - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -3346,7 +3344,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Lisää valintoja, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3356,7 +3354,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Lisää valintoja - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3366,7 +3364,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Tarkastele kohdetta - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -3375,17 +3373,30 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { - "message": "Assign collections" + "message": "Määritä kokoelmat" }, "copyEmail": { - "message": "Copy email" + "message": "Kopioi sähköpostiosoite" }, "copyPhone": { - "message": "Copy phone" + "message": "Kopioi puhelinnumero" }, "copyAddress": { - "message": "Copy address" + "message": "Kopioi osoite" }, "adminConsole": { "message": "Hallintapaneelista" @@ -3439,7 +3450,7 @@ } }, "itemsWithNoFolder": { - "message": "Kohteet, joilla ei ole kansioita" + "message": "Kansiottomat kohteet" }, "organizationIsDeactivated": { "message": "Organisaatio on poistettu käytöstä" diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 468e2a503f6..639300f7899 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Pagkakakilanlan" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Kasaysayan ng Password" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 8bb8cfe537b..fadf74c5d78 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identité" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Historique des mots de passe" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Effacer les filtres ou essayer un autre terme de recherche" }, - "copyInfoLabel": { - "message": "Copier les informations, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copier les informations - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copier la note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copier la note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assigner une collection" }, diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index cf38b90e8fa..9075adaaf64 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identidade" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Historial de contrasinais" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index b5cbb79ca17..cea1ab207ab 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -393,10 +393,10 @@ "message": "Unfavorite" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "פריט נוסף למועדפים" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "פריט הוסר מהמועדפים" }, "notes": { "message": "הערות" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "זהות" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "היסטוריית סיסמאות" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 741c873c65c..3232d9084e1 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "पहचान" }, + "newItemHeader": { + "message": "नया $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "$TYPE$ संपादन", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "पासवर्ड इतिहास" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 62b987fc3aa..144a27769ce 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitet" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Povijest" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 432ab7ec26e..06c3b93eacb 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -393,10 +393,10 @@ "message": "Nem kedvenc" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Az elem bekerült a kedvencekhez." }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Az elem kikerült a kedvencekből." }, "notes": { "message": "Jegyzetek" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Személyazonosság" }, + "newItemHeader": { + "message": "Új $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "$TYPE$ szerkesztése", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Jelszó előzmények" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Töröljük a szűrőket vagy próbálkozzunk másik keresési kifejezéssel." }, - "copyInfoLabel": { - "message": "Infó másolása, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Infó másolása - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Jegyzet másolása, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Jegyzet másolása - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Automatikus kitöltés - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Nincsenek másolandó értékek." + }, "assignCollections": { "message": "Gyűjtemények hozzárendelése" }, diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 3f834efd68a..fab17ae40e4 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitas" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Riwayat Kata Sandi" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 72bc28c87eb..9ea42bba02a 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identità" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Cronologia delle password" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Cancella i filtri o prova un altro termine di ricerca" }, - "copyInfoLabel": { - "message": "Copia informazioni, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copia informazioni - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copia nota, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copia nota - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assegna raccolte" }, diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index 549b441e506..29f840ff849 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "ID" }, + "newItemHeader": { + "message": "$TYPE$ を新規作成", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "$TYPE$ を編集", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "パスワードの履歴" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "フィルタをクリアするか、別の検索ワードをお試しください" }, - "copyInfoLabel": { - "message": "$ITEMNAME$ の情報をコピー", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "情報をコピー - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "$ITEMNAME$ のメモをコピー", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "メモをコピー - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "自動入力 - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "コピーする値がありません" + }, "assignCollections": { "message": "コレクションを割り当て" }, diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 1129d83b6cc..baee54e6380 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index e4b83601fe4..2360493fab4 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index e0e5d75cecd..45fbf95858a 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "ಗುರುತಿಸುವಿಕೆ" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "ಪಾಸ್ವರ್ಡ್ ಇತಿಹಾಸ" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 58d8d01b907..d7f2de56bb8 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -173,16 +173,16 @@ "message": "웹 앱에서 계속하시겠용?" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "웹 앱에서 Bitwarden 계정의 더 많은 기능을 탐색해보세요." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "도움말 센터로 이동" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "Bitwarden의 자세한 사용법은 도움말 센터에서 확인하세요." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "브라우저 확장 스토어로 이동하시겠습니까?" }, "continueToBrowserExtensionStoreDesc": { "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." @@ -205,7 +205,7 @@ "message": "로그아웃" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "Bitwarden 에 대하여" }, "about": { "message": "정보" @@ -390,7 +390,7 @@ "message": "즐겨찾기" }, "unfavorite": { - "message": "Unfavorite" + "message": "즐겨찾기 해제" }, "itemAddedToFavorites": { "message": "Item added to favorites" @@ -420,7 +420,7 @@ "message": "열기" }, "launchWebsite": { - "message": "Launch website" + "message": "웹사이트 열기" }, "website": { "message": "웹 사이트" @@ -435,7 +435,7 @@ "message": "기타" }, "unlockMethods": { - "message": "Unlock options" + "message": "잠금 해제 옵션" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "잠금 해제 방법을 설정하여 보관함의 시간 초과 동작을 변경하세요." @@ -444,10 +444,10 @@ "message": "설정에서 잠금 해제 수단 설정하기" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "세션 만료" }, "otherOptions": { - "message": "Other options" + "message": "기타 옵션" }, "rateExtension": { "message": "확장 프로그램 평가" @@ -722,7 +722,7 @@ "message": "\"로그인 추가 알림\"을 사용하면 새 로그인을 사용할 때마다 보관함에 그 로그인을 추가할 것인지 물어봅니다." }, "addLoginNotificationDescAlt": { - "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." + "message": "보관함에 항목이 없을 경우 추가하라는 메시지를 표시합니다. 모든 로그인된 계정에 적용됩니다." }, "showCardsCurrentTab": { "message": "탭 페이지에 카드 표시" @@ -754,10 +754,10 @@ "message": "현재 로그인으로 업데이트할 건지 묻기" }, "changedPasswordNotificationDesc": { - "message": "Ask to update a login's password when a change is detected on a website." + "message": "웹사이트에서 변경 사항이 감지되면 로그인 비밀번호를 업데이트하라는 메시지를 표시합니다." }, "changedPasswordNotificationDescAlt": { - "message": "Ask to update a login's password when a change is detected on a website. Applies to all logged in accounts." + "message": "웹사이트에서 변경 사항이 감지되면 로그인 비밀번호를 업데이트하라는 메시지를 표시합니다. 모든 로그인된 계정에 적용됩니다." }, "enableUsePasskeys": { "message": "패스키를 저장 및 사용할지 묻기" @@ -778,7 +778,7 @@ "message": "잠금 해제" }, "additionalOptions": { - "message": "Additional options" + "message": "추가 옵션" }, "enableContextMenuItem": { "message": "Show context menu options" @@ -803,7 +803,7 @@ "message": "애플리케이션의 색상 테마를 변경합니다." }, "themeDescAlt": { - "message": "Change the application's color theme. Applies to all logged in accounts." + "message": "애플리케이션 색상 테마를 변경합니다. 모든 로그인된 계정에 적용됩니다." }, "dark": { "message": "어두운 테마", @@ -830,7 +830,7 @@ "message": "This file export will be password protected and require the file password to decrypt." }, "filePassword": { - "message": "File password" + "message": "파일 비밀번호" }, "exportPasswordDescription": { "message": "This password will be used to export and import this file" @@ -842,10 +842,10 @@ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." }, "exportTypeHeading": { - "message": "Export type" + "message": "내보내기 유형" }, "accountRestricted": { - "message": "Account restricted" + "message": "계정 제한됨" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { "message": "“File password” and “Confirm file password“ do not match." @@ -1159,28 +1159,28 @@ "message": "환경 URL 값을 저장했습니다." }, "showAutoFillMenuOnFormFields": { - "message": "Show auto-fill menu on form fields", + "message": "입력 필드에 자동 완성 메뉴 표시", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "모든 로그인된 계정에 적용됩니다." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser’s built in password manager settings to avoid conflicts." + "message": "충돌을 방지하기 위해 브라우저의 기본 암호 관리 설정을 해제합니다." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edit browser settings." }, "autofillOverlayVisibilityOff": { - "message": "Off", + "message": "끄기", "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "필드가 선택되었을 때 (포커스 상태)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { - "message": "When auto-fill icon is selected", + "message": "자동 완성 아이콘이 선택되었을 때", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoad": { @@ -1190,7 +1190,7 @@ "message": "로그인 양식을 감지하면 웹 페이지 로드 시 자동 완성을 자동으로 수행합니다." }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "취약하거나 신뢰할 수 없는 웹사이트 페이지 로드 시 자동 완성이 악용될 수 있습니다." }, "learnMoreAboutAutofill": { "message": "Learn more about auto-fill" @@ -1273,13 +1273,13 @@ "message": "Show a recognizable image next to each login." }, "faviconDescAlt": { - "message": "Show a recognizable image next to each login. Applies to all logged in accounts." + "message": "각 로그인 정보 옆에 인식할 수 있는 이미지를 표시합니다. 모든 로그인된 계정에 적용됩니다." }, "enableBadgeCounter": { - "message": "Show badge counter" + "message": "배지 갯수 표시" }, "badgeCounterDesc": { - "message": "Indicate how many logins you have for the current web page." + "message": "현재 웹 페이지에 저장된 로그인 정보의 수를 표시합니다." }, "cardholderName": { "message": "카드 소유자 이름" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "신원" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "비밀번호 변경 기록" }, @@ -1557,7 +1575,7 @@ "description": "ex. Date this item was updated" }, "dateCreated": { - "message": "Created", + "message": "생성됨", "description": "ex. Date this item was created" }, "datePasswordUpdated": { @@ -1614,7 +1632,7 @@ "message": "잘못된 PIN 코드입니다." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "잘못된 PIN 입력 시도가 너무 많습니다. 로그아웃 합니다." }, "unlockWithBiometrics": { "message": "생체 인식을 사용하여 잠금 해제" @@ -1712,13 +1730,13 @@ "message": "마스터 비밀번호 설정" }, "currentMasterPass": { - "message": "Current master password" + "message": "현재 마스터 비밀번호" }, "newMasterPass": { - "message": "New master password" + "message": "새 마스터 비밀번호" }, "confirmNewMasterPass": { - "message": "Confirm new master password" + "message": "새 마스터 비밀번호 확인" }, "masterPasswordPolicyInEffect": { "message": "하나 이상의 단체 정책이 마스터 비밀번호가 다음 사항을 따르도록 요구합니다:" @@ -2137,7 +2155,7 @@ "message": "폴더 선택..." }, "noFoldersFound": { - "message": "No folders found", + "message": "폴더를 찾을 수 없습니다.", "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { @@ -2149,7 +2167,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { - "message": "Verification required", + "message": "인증 필요", "description": "Default title for the user verification dialog." }, "hours": { @@ -2310,7 +2328,7 @@ "message": "서비스" }, "forwardedEmail": { - "message": "Forwarded email alias" + "message": "포워딩된 이메일 별칭" }, "forwardedEmailDesc": { "message": "Generate an email alias with an external forwarding service." @@ -2418,7 +2436,7 @@ } }, "hostname": { - "message": "Hostname", + "message": "호스트 이름", "description": "Part of a URL." }, "apiAccessToken": { @@ -2431,7 +2449,7 @@ "message": "키 커넥터 오류: 키 커넥터가 사용 가능한지 및 정상적으로 작동하고 있는지 확인해주세요." }, "premiumSubcriptionRequired": { - "message": "Premium subscription required" + "message": "프리미엄 구독이 필요합니다" }, "organizationIsDisabled": { "message": "Organization suspended." @@ -2458,13 +2476,13 @@ "message": "to reset to pre-configured settings" }, "serverVersion": { - "message": "Server version" + "message": "서버 버전" }, "selfHostedServer": { - "message": "self-hosted" + "message": "자체 호스팅" }, "thirdParty": { - "message": "Third-party" + "message": "제 3자" }, "thirdPartyServerMessage": { "message": "Connected to third-party server implementation, $SERVERNAME$. Please verify bugs using the official server, or report them to the third-party server.", @@ -2491,13 +2509,13 @@ "message": "Logging in as" }, "notYou": { - "message": "Not you?" + "message": "본인이 아닌가요?" }, "newAroundHere": { - "message": "New around here?" + "message": "새로 찾아오셨나요?" }, "rememberEmail": { - "message": "Remember email" + "message": "이메일 기억하기" }, "loginWithDevice": { "message": "Log in with device" @@ -2575,13 +2593,13 @@ "message": "Got it" }, "autofillSettings": { - "message": "Auto-fill settings" + "message": "자동 완성 설정" }, "autofillShortcut": { - "message": "Auto-fill keyboard shortcut" + "message": "자동 완성 키보드 단축키" }, "autofillShortcutNotSet": { - "message": "The auto-fill shortcut is not set. Change this in the browser's settings." + "message": "자동 완성 단축키가 설정되지 않았습니다. 브라우저 설정에서 단축키를 변경하세요." }, "autofillShortcutText": { "message": "The auto-fill shortcut is: $COMMAND$. Change this in the browser's settings.", @@ -2611,7 +2629,7 @@ "message": "Device approval required. Select an approval option below:" }, "rememberThisDevice": { - "message": "Remember this device" + "message": "이 기기 기억하기" }, "uncheckIfPublicDevice": { "message": "Uncheck if using a public device" @@ -2620,7 +2638,7 @@ "message": "Approve from your other device" }, "requestAdminApproval": { - "message": "Request admin approval" + "message": "관리자 승인 필요" }, "approveWithMasterPassword": { "message": "Approve with master password" @@ -2657,16 +2675,16 @@ "message": "Access denied. You do not have permission to view this page." }, "general": { - "message": "General" + "message": "일반" }, "display": { - "message": "Display" + "message": "화면" }, "accountSuccessfullyCreated": { - "message": "Account successfully created!" + "message": "계정이 생성되었습니다!" }, "adminApprovalRequested": { - "message": "Admin approval requested" + "message": "관리자 승인 필요" }, "adminApprovalRequestSentToAdmins": { "message": "Your request has been sent to your admin." @@ -2693,7 +2711,7 @@ "message": "required" }, "search": { - "message": "Search" + "message": "검색" }, "inputMinLength": { "message": "Input must be at least $COUNT$ characters long.", @@ -2741,7 +2759,7 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "하나 이상의 이메일이 유효하지 않습니다." }, "inputTrimValidator": { "message": "Input must not contain only whitespace.", @@ -2811,7 +2829,7 @@ "description": "Notification message for when an import is in progress." }, "dataSuccessfullyImported": { - "message": "Data successfully imported!", + "message": "데이터 가져오기 성공!", "description": "Notification message for when an import has completed successfully." }, "dataImportFailed": { @@ -2857,7 +2875,7 @@ "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "계정 잠금 해제", "description": "Button text to display in overlay when the account is locked." }, "fillCredentialsFor": { @@ -2873,7 +2891,7 @@ "description": "Text to show in overlay if there are no matching items" }, "newItem": { - "message": "New item", + "message": "새 항목", "description": "Button text to display in overlay when there are no matching items" }, "addNewVaultItem": { @@ -2919,7 +2937,7 @@ } }, "tryAgain": { - "message": "Try again" + "message": "다시 시도" }, "verificationRequiredForActionSetPinToContinue": { "message": "Verification required for this action. Set a PIN to continue." @@ -2979,13 +2997,13 @@ "message": "Popout extension" }, "launchDuo": { - "message": "Launch Duo" + "message": "Duo 실행" }, "importFormatError": { - "message": "Data is not formatted correctly. Please check your import file and try again." + "message": "데이터의 포맷이 올바르지 않습니다. 불러올 파일을 확인하고 다시 시도해 주십시오." }, "importNothingError": { - "message": "Nothing was imported." + "message": "아무것도 가져오지 못했습니다." }, "importEncKeyError": { "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." @@ -3232,7 +3250,7 @@ "description": "Label indicating the most common import formats" }, "overrideDefaultBrowserAutofillTitle": { - "message": "Make Bitwarden your default password manager?", + "message": "Bitwarden을 기본 비밀번호 관리자로 지정하시겠습니까?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { @@ -3240,7 +3258,7 @@ "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { - "message": "Make Bitwarden your default password manager", + "message": "Bitwarden을 기본 비밀번호 관리자로 지정", "description": "Label for the setting that allows overriding the default browser autofill settings" }, "privacyPermissionAdditionNotGrantedTitle": { @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, @@ -3391,13 +3402,13 @@ "message": "Admin Console" }, "accountSecurity": { - "message": "Account security" + "message": "계정 보안" }, "notifications": { - "message": "Notifications" + "message": "알림" }, "appearance": { - "message": "Appearance" + "message": "화면 스타일" }, "errorAssigningTargetCollection": { "message": "Error assigning target collection." diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 8dd871d7ef3..b906e405b14 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Tapatybė" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Slaptažodžio istorija" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index fcc4851d390..2da50646840 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -390,13 +390,13 @@ "message": "Izlasē" }, "unfavorite": { - "message": "Unfavorite" + "message": "Noņemt no izlases" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Vienums pievienots izlasē" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Vienums noņemts no izlases" }, "notes": { "message": "Piezīmes" @@ -420,7 +420,7 @@ "message": "Palaist" }, "launchWebsite": { - "message": "Launch website" + "message": "Atvērt tīmekļvietni" }, "website": { "message": "Tīmekļa vietne" @@ -612,7 +612,7 @@ "message": "Atteicies" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Notika izrakstīšanās no Tava konta." }, "loginExpired": { "message": "Pieteikšanās sesija ir beigusies." @@ -1123,13 +1123,13 @@ "message": "Norādīt pašuzstādīta Bitwarden pamata URL." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Jānorāda sava pašizvietotā Bitward servera pamata URL. Piemērs: https://bitwarden.uznemums.lv" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Papildu konfigurācijā ir iespējams norādīt URL katram pakalpojumam atsevišķi." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Jāpievieno vai no servera pamata URL vai vismaz viena pielāgota vide." }, "customEnvironment": { "message": "Pielāgota vide" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitāte" }, + "newItemHeader": { + "message": "Jauns/a $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Labot $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Paroļu vēsture" }, @@ -1444,7 +1462,7 @@ "message": "Krājumi" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ krājumi", "placeholders": { "count": { "content": "$1", @@ -1682,7 +1700,7 @@ "message": "Automātiski aizpildīt un saglabāt" }, "fillAndSave": { - "message": "Fill and save" + "message": "Aizpildīt un saglabāt" }, "autoFillSuccessAndSavedUri": { "message": "Automātiski aizpildīts vienums un saglabāts URI" @@ -1781,10 +1799,10 @@ "message": "Labi" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Piekļuves pilnvaras atsvaizināšanas kļūda" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Netika atrastas atsvaidzināšanas pilnvaras vai API atslēgas. Lūgums mēģināt izrakstīties un atkal pieteikties." }, "desktopSyncVerificationTitle": { "message": "Darbvirsmas sinhronizācijas apstiprinājums" @@ -3305,18 +3323,8 @@ "clearFiltersOrTryAnother": { "message": "Jānotīra atlases vērtības vai jāmēģina cits meklēšanas vaicājums" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Ievietot starpliktuvē informāciju - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -3325,18 +3333,8 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Ievietot starpliktuvē piezīmi - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -3346,7 +3344,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Vairāk iespēju, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3356,7 +3354,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Vairāk iespēju - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3366,7 +3364,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Skatīt vienumu - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -3375,17 +3373,30 @@ } } }, + "autofillTitle": { + "message": "Automātiski aizpildīt - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Nav vērtību, ko ievietot starpliktuvē" + }, "assignCollections": { - "message": "Assign collections" + "message": "Piešķirt krājumus" }, "copyEmail": { - "message": "Copy email" + "message": "Ievietot starpliktuvē e-pasta adresi" }, "copyPhone": { - "message": "Copy phone" + "message": "Ievietot starpliktuvē tālruņa numuru" }, "copyAddress": { - "message": "Copy address" + "message": "Ievietot starpliktuvē adresi" }, "adminConsole": { "message": "pārvaldības konsolē," @@ -3439,12 +3450,12 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "Vienumi bez mapes" }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "Apvienība ir atspējota" }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "Atspējotu apvienību vienumiem nevar piekļūt. Jāsazinās ar apvienības īpašnieku, lai iegūtu palīdzību." } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 7e578136330..5ee6029465b 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "ഐഡന്റിറ്റി" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "പാസ്സ്‌വേഡ് നാൾവഴി" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 4bbc32ef565..ce8ef907f8b 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index e4b83601fe4..2360493fab4 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 7552c982967..79a6284fa3a 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitet" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Passordhistorikk" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index e4b83601fe4..2360493fab4 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 62a418d0245..93820cd208d 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identiteit" }, + "newItemHeader": { + "message": "Nieuw $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "$TYPE$ bewerken", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Geschiedenis" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Wis filters of probeer een andere zoekterm" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Automatisch invullen - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Geen waarden om te kopiëren" + }, "assignCollections": { "message": "Collecties toewijzen" }, diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index e4b83601fe4..2360493fab4 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index e4b83601fe4..2360493fab4 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index aa48d596a42..e8c888067ec 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Tożsamość" }, + "newItemHeader": { + "message": "Nowy $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edytuj $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Historia hasła" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Wyczyść filtry lub użyj innej frazy" }, - "copyInfoLabel": { - "message": "Skopiuj informacje, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Skopiuj informacje - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Skopiuj notatkę, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Skopiuj notatkę - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Autouzupełnij - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Brak wartości do skopiowania" + }, "assignCollections": { "message": "Przypisz kolekcje" }, diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index dd540bd6176..2fd0a0a8d75 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identidade" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Histórico de Senha" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Limpar filtros ou tentar outro termo de pesquisa" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 7fe4400078e..81468364b7d 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identidade" }, + "newItemHeader": { + "message": "Novo(a) $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Editar $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Histórico de palavras-passe" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Limpe os filtros ou tente outro termo de pesquisa" }, - "copyInfoLabel": { - "message": "Copiar informações, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copiar informações - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copiar nota, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copiar nota - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Preencher automaticamente - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Não há valores a copiar" + }, "assignCollections": { "message": "Atribuir coleções" }, diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 4fb528a61bf..f0be1aa0b06 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitate" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Istoric parole" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index d6dab1dd477..86ffaa4946c 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -393,10 +393,10 @@ "message": "Удалить из избранного" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Элемент добавлен в избранное" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Элемент удален из избранного" }, "notes": { "message": "Заметки" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Личная информация" }, + "newItemHeader": { + "message": "Новый $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Изменить $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "История паролей" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Очистите фильтры или попробуйте другой поисковый запрос" }, - "copyInfoLabel": { - "message": "Скопировать информацию, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Скопировать информацию - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Скопировать заметку, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Скопировать заметку - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Автозаполнение - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Нет значений для копирования" + }, "assignCollections": { "message": "Назначить коллекции" }, diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 5dfeef73bb4..8e221eecab9 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "අනන්යතාවය" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "මුරපද ඉතිහාසය" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 2050bd87bd4..76d28910fe5 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -393,10 +393,10 @@ "message": "Odstrániť z obľúbených" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Položka pridaná medzi obľúbené" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Položka odobraná z obľúbených" }, "notes": { "message": "Poznámky" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identita" }, + "newItemHeader": { + "message": "Nové $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Upraviť $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "História hesla" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Vymažte filtre alebo zmeňte vyhľadávaný výraz" }, - "copyInfoLabel": { - "message": "Skopírovať info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Skopírovať info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Skopírovať poznámku, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Skopírovať poznámku - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Automatické vyplnenie - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Nie je čo kopírovať" + }, "assignCollections": { "message": "Prideliť zbierky" }, diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 1f2c35a4bea..7a46d0e50f6 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identiteta" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Zgodovina gesel" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 7dad0623e12..0a29c4c2e77 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Идентитет" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Историја Лозинке" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Обришите филтере или покушајте са другим термином" }, - "copyInfoLabel": { - "message": "Копирај информације, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Копирај информације - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Копирај Белешку, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Копирај Белешку - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Додели колекције" }, diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 411c1605ef8..2d1ec183417 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identitet" }, + "newItemHeader": { + "message": "Ny $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Redigera $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Lösenordshistorik" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Tilldela samlingar" }, diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index e4b83601fe4..2360493fab4 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Identity" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Password history" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 27988854f58..a2a64774a0f 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "ข้อมูลระบุตัวตน" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "ประวัติของรหัสผ่าน" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 56c3beb5105..192e27a98ab 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Kimlik" }, + "newItemHeader": { + "message": "Yeni $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Parola geçmişi" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Filtreleri temizleyin veya başka bir arama yapmayı deneyin" }, - "copyInfoLabel": { - "message": "Bilgileri kopyala, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Bilgileri kopyala - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Notu kopyala, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Notu kopyala - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Otomatik doldur - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Kopyalanacak değer yok" + }, "assignCollections": { "message": "Koleksiyon ata" }, diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 845774e81a6..d8adaaf4508 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -393,10 +393,10 @@ "message": "Вилучити з обраного" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Запис додано до обраного" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Запис вилучено з обраного" }, "notes": { "message": "Нотатки" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Особисті дані" }, + "newItemHeader": { + "message": "Новий $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Редагувати $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Історія паролів" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Скиньте фільтри або спробуйте іншу умову пошуку" }, - "copyInfoLabel": { - "message": "Копіювати інформацію, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Копіювати інформацію – $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Копіювати нотатку, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Копіювати нотатку – $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Автозаповнення – $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "Немає значень для копіювання" + }, "assignCollections": { "message": "Призначити збірки" }, diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index bb19edc420f..e2c6cac2809 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "Danh tính" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "Lịch sử mật khẩu" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 4232403aa32..abe02b08b00 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -390,13 +390,13 @@ "message": "收藏" }, "unfavorite": { - "message": "Unfavorite" + "message": "取消收藏" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "项目已添加到收藏夹" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "项目已移出收藏夹" }, "notes": { "message": "备注" @@ -420,7 +420,7 @@ "message": "前往" }, "launchWebsite": { - "message": "Launch website" + "message": "启动网站" }, "website": { "message": "网站" @@ -612,7 +612,7 @@ "message": "已注销" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "您已注销您的账户。" }, "loginExpired": { "message": "您的登录会话已过期。" @@ -1123,13 +1123,13 @@ "message": "指定您本地托管的 Bitwarden 安装的基础 URL。" }, "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 或至少添加一个自定义环境。" }, "customEnvironment": { "message": "自定义环境" @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "身份" }, + "newItemHeader": { + "message": "新增 $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "编辑 $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "密码历史记录" }, @@ -1444,7 +1462,7 @@ "message": "集合" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ 个集合", "placeholders": { "count": { "content": "$1", @@ -1682,7 +1700,7 @@ "message": "自动填充并保存" }, "fillAndSave": { - "message": "Fill and save" + "message": "填充并保存" }, "autoFillSuccessAndSavedUri": { "message": "项目已自动填充且 URI 已保存" @@ -1781,10 +1799,10 @@ "message": "确定" }, "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 密钥。请尝试注销然后重新登录。" }, "desktopSyncVerificationTitle": { "message": "桌面同步验证" @@ -2675,7 +2693,7 @@ "message": "批准后,您将收到通知。" }, "troubleLoggingIn": { - "message": "登录遇到问题?" + "message": "登录遇到问题吗?" }, "loginApproved": { "message": "登录已批准" @@ -3305,18 +3323,8 @@ "clearFiltersOrTryAnother": { "message": "清除筛选器或尝试另一个搜索词" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "复制信息 - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -3325,18 +3333,8 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "复制备注 - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -3346,7 +3344,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "更多选项,$ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3356,7 +3354,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "更多选项 - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -3366,7 +3364,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "查看项目 - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -3375,17 +3373,30 @@ } } }, + "autofillTitle": { + "message": "自动填充 - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "没有要复制的值" + }, "assignCollections": { - "message": "Assign collections" + "message": "分配集合" }, "copyEmail": { - "message": "Copy email" + "message": "复制电子邮件地址" }, "copyPhone": { - "message": "Copy phone" + "message": "复制电话号码" }, "copyAddress": { - "message": "Copy address" + "message": "复制地址" }, "adminConsole": { "message": "管理控制台" @@ -3426,7 +3437,7 @@ } }, "new": { - "message": "新建" + "message": "新增" }, "removeItem": { "message": "删除 $NAME$", @@ -3439,12 +3450,12 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "无文件夹的项目" }, "organizationIsDeactivated": { "message": "组织已停用" }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "无法访问已停用组织中的项目。请联系您的组织所有者获取协助。" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 7d00a68d88b..a09d6750a01 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -1434,6 +1434,24 @@ "typeIdentity": { "message": "身分" }, + "newItemHeader": { + "message": "New $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, + "editItemHeader": { + "message": "Edit $TYPE$", + "placeholders": { + "type": { + "content": "$1", + "example": "Login" + } + } + }, "passwordHistory": { "message": "密碼歷史記錄" }, @@ -3305,16 +3323,6 @@ "clearFiltersOrTryAnother": { "message": "Clear filters or try another search term" }, - "copyInfoLabel": { - "message": "Copy info, $ITEMNAME$", - "description": "Aria label for a button that opens a menu with options to copy information from an item.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Item" - } - } - }, "copyInfoTitle": { "message": "Copy info - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", @@ -3325,16 +3333,6 @@ } } }, - "copyNoteLabel": { - "message": "Copy Note, $ITEMNAME$", - "description": "Aria label for a button copies a note to the clipboard.", - "placeholders": { - "itemname": { - "content": "$1", - "example": "Secret Note Item" - } - } - }, "copyNoteTitle": { "message": "Copy Note - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", @@ -3375,6 +3373,19 @@ } } }, + "autofillTitle": { + "message": "Auto-fill - $ITEMNAME$", + "description": "Title for a button that auto-fills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + } + } + }, + "noValuesToCopy": { + "message": "No values to copy" + }, "assignCollections": { "message": "Assign collections" }, diff --git a/apps/browser/store/locales/ko/copy.resx b/apps/browser/store/locales/ko/copy.resx index 595663b1cae..a2fc4e19858 100644 --- a/apps/browser/store/locales/ko/copy.resx +++ b/apps/browser/store/locales/ko/copy.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden Password Manager + Bitwarden 비밀번호 관리자 집에서도, 직장에서도, 이동 중에도 Bitwarden은 비밀번호, 패스키, 민감 정보를 쉽게 보호합니다. diff --git a/apps/browser/store/locales/uk/copy.resx b/apps/browser/store/locales/uk/copy.resx index e74811a7751..6f994cd0bf1 100644 --- a/apps/browser/store/locales/uk/copy.resx +++ b/apps/browser/store/locales/uk/copy.resx @@ -124,48 +124,48 @@ Вдома, на роботі чи в дорозі, Bitwarden захищає ваші паролі, ключі доступу та конфіденційну інформацію. - Визнаний найкращим менеджером паролів за версією PCMag, WIRED, The Verge, CNET, G2 та інших! + Визнаний найкращим менеджером паролів виданнями PCMag, WIRED, The Verge, CNET, G2 та іншими! ЗАХИСТІТЬ СВОЄ ЦИФРОВЕ ЖИТТЯ -Убезпечте своє цифрове життя та захистіться від витоку даних, створивши та зберігши унікальні, надійні паролі для кожного облікового запису. Зберігайте всі дані в наскрізному зашифрованому сховищі паролів, доступ до якого маєте лише ви. +Убезпечте своє цифрове життя та захистіться від витоків даних, генеруючи та зберігаючи унікальні надійні паролі для кожного облікового запису. Зберігайте все в наскрізно зашифрованому сховищі паролів, доступ до якого маєте тільки ви. -ОТРИМУВАТИ ДОСТУП ДО СВОЇХ ДАНИХ БУДЬ-ДЕ, БУДЬ-КОЛИ, БУДЬ НА ЯКОМУ ПРИСТРОЇ -Легко керуйте, зберігайте, захищайте та діліться необмеженою кількістю паролів на необмеженій кількості пристроїв без обмежень. +ДОСТУП ДО ДАНИХ БУДЬ-ДЕ, БУДЬ-КОЛИ, НА БУДЬ-ЯКОМУ ПРИСТРОЇ +Легко керуйте, зберігайте, захищайте та діліться необмеженою кількістю паролів на необмеженій кількості пристроїв. -КОЖЕН ПОВИНЕН МАТИ ІНСТРУМЕНТИ, ЩОБ ЗАЛИШАТИСЯ В БЕЗПЕЦІ В ІНТЕРНЕТІ -Користуйтеся Bitwarden безкоштовно, без реклами і без продажу даних. Bitwarden вважає, що кожен повинен мати можливість залишатися в безпеці в Інтернеті. Преміум-плани пропонують доступ до розширених функцій. +КОЖЕН ПОВИНЕН МАТИ ІНСТРУМЕНТИ ДЛЯ БЕЗПЕКИ В ІНТЕРНЕТІ +Використовуйте Bitwarden безплатно без реклами або продажу даних. Bitwarden вважає, що кожен повинен мати можливість залишатися в безпеці в Інтернеті. Завдяки тарифним планам Преміум можна отримати доступ до розширених можливостей. -РОЗШИРЮЙТЕ МОЖЛИВОСТІ СВОЇХ КОМАНД ЗА ДОПОМОГОЮ BITWARDEN -Плани для Команд та Підприємства містять професійні бізнес-функції. Деякі приклади включають інтеграцію SSO, самостійний хостинг, інтеграцію каталогів і забезпечення SCIM, глобальні політики, доступ до API, журнали подій і багато іншого. +РОЗШИРТЕ МОЖЛИВОСТІ СВОЇХ КОМАНД ЗА ДОПОМОГОЮ BITWARDEN +Плани для команд і компаній мають професійні бізнес-функції. Вони передбачають інтеграцію єдиного входу (SSO), власне розміщення, інтеграцію каталогів та забезпечення SCIM, глобальні політики, доступ до API, журнали подій тощо. -Використовуйте Bitwarden, щоб захистити своїх співробітників і ділитися конфіденційною інформацією з колегами. +Використовуйте Bitwarden для захисту персоналу та обміну конфіденційною інформацією з колегами. -Більше причин вибрати Bitwarden: +Інші причини для вибору Bitwarden: Шифрування світового класу -Паролі захищені вдосконаленим наскрізним шифруванням (біт AES-256, солоний хештег і PBKDF2 SHA-256), тому ваші дані залишаються надійно захищеними та конфіденційними. +Паролі захищаються розширеним наскрізним шифруванням (AES-256, сіллю хешування і PBKDF2 SHA-256), тому ваші дані завжди зберігаються приватно і в безпеці. -Аудит третьої сторони -Bitwarden регулярно проводить комплексні сторонні аудити безпеки з відомими компаніями, що займаються безпекою. Ці щорічні аудити включають оцінку вихідного коду та тестування на проникнення на всіх IP-адресах, серверах і веб-додатках Bitwarden. +Сторонні аудити +Bitwarden регулярно проводить комплексні аудити безпеки із залученням третіх сторін – відомих компаній у сфері безпеки. Під час цих щорічних аудитів проводиться оцінка програмного коду і тестування на проникнення через IP-адреси Bitwarden, сервери та вебпрограми. -Розширений 2FA -Захистіть свій вхід за допомогою стороннього автентифікатора, кодів, надісланих електронною поштою, або облікових даних FIDO2 WebAuthn, наприклад, апаратного ключа безпеки або пароля. +Розширена 2FA +Захистіть свої дані входу за допомогою стороннього автентифікатора, кодів, що надсилаються електронною поштою, або облікових даних FIDO2 WebAuthn, як-от апаратний ключ безпеки або ключ доступу. -Bitwarden Send -Передавайте дані безпосередньо іншим, зберігаючи при цьому наскрізну зашифровану безпеку та обмежуючи вразливість. +Відправлення Bitwarden +Передавайте дані безпосередньо іншим користувачам, зберігаючи наскрізне шифрування та обмежуючи їх викриття. Вбудований генератор -Створюйте довгі, складні та відмінні паролі та унікальні імена користувачів для кожного сайту, який ви відвідуєте. Інтеграція з провайдерами псевдонімів електронної пошти для додаткової конфіденційності. +Створюйте довгі, складні та чіткі паролі, а також унікальні імена користувачів для кожного сайту, який ви відвідуєте. Користуйтеся інтеграцією з провайдерами псевдонімів електронної пошти для забезпечення додаткової приватності. -Глобальні переклади -Переклади Bitwarden існують для більш ніж 60 мов, перекладені світовою спільнотою за допомогою Crowdin. +Переклад різними мовами +Bitwarden перекладено понад 60 мовами завдяки зусиллям нашої світової спільноти на Crowdin. -Крос-платформні додатки -Захищайте конфіденційні дані у своєму сховищі Bitwarden Vault та діліться ними з будь-якого браузера, мобільного пристрою, настільної операційної системи тощо. +Програми для різних платформ +Захищайте та діліться конфіденційними даними в межах свого сховища Bitwarden з будь-якого браузера, мобільного пристрою або комп'ютерної ОС, а також інших можливостей. -Bitwarden захищає більше, ніж просто паролі -Наскрізні рішення для управління зашифрованими обліковими даними від Bitwarden дозволяють організаціям захистити все, включаючи секрети розробників і досвід роботи з ключами. Відвідайте Bitwarden.com, щоб дізнатися більше про Bitwarden Secrets Manager і Bitwarden Passwordless.dev! +Bitwarden захищає не лише паролі +Комплексні рішення для керування наскрізно зашифрованими обліковими даними від Bitwarden дають змогу організаціям захищати все, включно з секретами розробників та ключами доступу. Відвідайте Bitwarden.com, щоб дізнатися більше про Менеджер секретів Bitwarden і Bitwarden Passwordless.dev! From 66dc01cc62a04bece15d0ba1961d28ab00a8587e Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Sun, 16 Jun 2024 14:01:48 -0400 Subject: [PATCH 27/29] [PM-7930] Add ability to pop out extension to user decryption options component (#9037) * Added app-pop-out to components * Removed debugging. * Removed pop-out from login via auth request. * Undid header changes. --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com> --- .../login-decryption-options.component.html | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.html b/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.html index 32e3ea0c598..e996f9a6ff4 100644 --- a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.html +++ b/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.html @@ -1,10 +1,13 @@
-
-

+ +
+ +
+

{{ "loginInitiated" | i18n }}

-

- +
+