From d9550fcecb46d823c47da39e8ef9da5d7174192c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 11:22:39 +0200 Subject: [PATCH 01/75] fix(deps): pin dependencies (#5438) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Hinton --- apps/desktop/desktop_native/Cargo.lock | 6 ++-- apps/desktop/desktop_native/Cargo.toml | 50 +++++++++++++------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 1d2d79f2e9..468bdbc7b0 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -48,9 +48,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c70beb79cbb5ce9c4f8e20849978f34225931f665bb49efa6982875a4d5facb3" +checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813" [[package]] name = "block-buffer" @@ -578,7 +578,7 @@ version = "2.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "556470a21074b55be8adee5f27ca04389cfdaca323a28b4b0e9c15466de94731" dependencies = [ - "bitflags 2.1.0", + "bitflags 2.2.1", "ctor", "napi-derive", "napi-sys", diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml index 60b330ea75..f005ed9d50 100644 --- a/apps/desktop/desktop_native/Cargo.toml +++ b/apps/desktop/desktop_native/Cargo.toml @@ -9,30 +9,30 @@ version = "0.0.0" crate-type = ["cdylib"] [features] -default=[] -manual_test=[] +default = [] +manual_test = [] [dependencies] -aes = "0.8.2" -anyhow = "1.0" -base64 = "0.21.0" -cbc = { version = "0.1.2", features = ["alloc"] } -napi = {version = "2.9.1", features = ["async"]} -napi-derive = "2.9.1" -rand = "0.8.5" -retry = "2.0.0" -scopeguard = "1.1.0" -sha2 = "0.10.6" -thiserror = "1.0.38" -tokio = {version = "1.17.0", features = ["full"]} -typenum = "1.16.0" +aes = "=0.8.2" +anyhow = "=1.0.70" +base64 = "=0.21.0" +cbc = { version = "=0.1.2", features = ["alloc"] } +napi = { version = "=2.12.4", features = ["async"] } +napi-derive = "=2.12.3" +rand = "=0.8.5" +retry = "=2.0.0" +scopeguard = "=1.1.0" +sha2 = "=0.10.6" +thiserror = "=1.0.40" +tokio = { version = "=1.27.0", features = ["full"] } +typenum = "=1.16.0" [build-dependencies] -napi-build = "2.0.1" +napi-build = "=2.0.1" [target.'cfg(windows)'.dependencies] -widestring = "0.5.1" -windows = {version = "0.48.0", features = [ +widestring = "=0.5.1" +windows = { version = "=0.48.0", features = [ "Foundation", "Security_Credentials_UI", "Security_Cryptography", @@ -42,16 +42,16 @@ windows = {version = "0.48.0", features = [ "Win32_System_WinRT", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_WindowsAndMessaging", -]} +] } [target.'cfg(windows)'.dev-dependencies] -keytar = "0.1.6" +keytar = "=0.1.6" [target.'cfg(target_os = "macos")'.dependencies] -core-foundation = "0.9.3" -security-framework = "2.6.1" -security-framework-sys = "2.6.1" +core-foundation = "=0.9.3" +security-framework = "=2.8.2" +security-framework-sys = "=2.8.0" [target.'cfg(target_os = "linux")'.dependencies] -gio = "0.15.6" -libsecret = "0.1.4" +gio = "=0.15.12" +libsecret = "=0.1.5" From 665fe971e0f5640fd126cb18ea7d30574edb97b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 11:23:40 +0200 Subject: [PATCH 02/75] chore(deps): update dependency webpack-cli to v5 (#5458) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 94 +++++++++++++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d312f9952..ce3166df24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -175,7 +175,7 @@ "util": "0.12.5", "wait-on": "7.0.1", "webpack": "5.82.1", - "webpack-cli": "4.10.0", + "webpack-cli": "5.1.1", "webpack-dev-server": "4.15.0", "webpack-node-externals": "3.0.0" }, @@ -16049,34 +16049,42 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz", + "integrity": "sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==", "dev": true, + "engines": { + "node": ">=14.15.0" + }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", + "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", "dev": true, - "dependencies": { - "envinfo": "^7.7.3" + "engines": { + "node": ">=14.15.0" }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.4.tgz", + "integrity": "sha512-0xRgjgDLdz6G7+vvDLlaRpFatJaJ69uTalZLRSMX5B3VUrDmXcrVA3+6fXXQgmYz7bY9AAgs348XQdmtLsK41A==", "dev": true, + "engines": { + "node": ">=14.15.0" + }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -43907,44 +43915,42 @@ } }, "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.1.tgz", + "integrity": "sha512-OLJwVMoXnXYH2ncNGU8gxVpUtm3ybvdioiTvHgUyBuyMLKiVvWy+QObzBsMtp5pH7qQoEuWgeEUQ/sU3ZJFzAw==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", + "@webpack-cli/configtest": "^2.1.0", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.4", "colorette": "^2.0.14", - "commander": "^7.0.0", + "commander": "^10.0.1", "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", "webpack-merge": "^5.7.3" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=10.13.0" + "node": ">=14.15.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "webpack": "5.x.x" }, "peerDependenciesMeta": { "@webpack-cli/generators": { "optional": true }, - "@webpack-cli/migrate": { - "optional": true - }, "webpack-bundle-analyzer": { "optional": true }, @@ -43953,16 +43959,34 @@ } } }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-cli/node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/webpack-cli/node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "dependencies": { - "resolve": "^1.9.0" + "resolve": "^1.20.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 10.13.0" } }, "node_modules/webpack-dev-middleware": { diff --git a/package.json b/package.json index 1fc4f50849..5891939745 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "util": "0.12.5", "wait-on": "7.0.1", "webpack": "5.82.1", - "webpack-cli": "4.10.0", + "webpack-cli": "5.1.1", "webpack-dev-server": "4.15.0", "webpack-node-externals": "3.0.0" }, From 177d7952928b0196d27153f5f2a5e6957bf4bea4 Mon Sep 17 00:00:00 2001 From: Daniel James Smith Date: Tue, 16 May 2023 11:28:21 +0200 Subject: [PATCH 03/75] Remove tapable as dependency as we don't use it (#5457) tapable is a package which is used by other packages we depend on, but we don't actually use it anywhere. --- package-lock.json | 1 - package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce3166df24..4fbe4960de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -165,7 +165,6 @@ "storybook-addon-designs": "6.3.1", "style-loader": "3.3.2", "tailwindcss": "3.3.2", - "tapable": "1.1.3", "ts-jest": "28.0.8", "ts-loader": "9.4.2", "tsconfig-paths-webpack-plugin": "3.5.2", diff --git a/package.json b/package.json index 5891939745..c701317cdb 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,6 @@ "storybook-addon-designs": "6.3.1", "style-loader": "3.3.2", "tailwindcss": "3.3.2", - "tapable": "1.1.3", "ts-jest": "28.0.8", "ts-loader": "9.4.2", "tsconfig-paths-webpack-plugin": "3.5.2", From 1caae996ff012206199552610a12d34e3be95645 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 08:01:07 -0600 Subject: [PATCH 04/75] chore(deps): update crazy-max/ghaction-import-gpg digest to 72b6676 (#5446) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/version-bump.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml index 58b40bae25..cc6344617d 100644 --- a/.github/workflows/version-bump.yml +++ b/.github/workflows/version-bump.yml @@ -55,7 +55,7 @@ jobs: secrets: "github-gpg-private-key, github-gpg-private-key-passphrase" - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@c8bb57c57e8df1be8c73ff3d59deab1dbc00e0d1 # v5.3.0 + uses: crazy-max/ghaction-import-gpg@72b6676b71ab476b77e676928516f6982eef7a41 # v5.3.0 with: gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }} passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }} From c58b0c0753d97713552d080fba36125af68afb65 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 16 May 2023 10:20:40 -0400 Subject: [PATCH 05/75] Return error code when any tsc typecheck fails (#5459) * Return error code when any tsc typecheck fails * Try with bash `sh ./scripts/test-types.s` resulted in errors missing `[[`, which is a bash builtin. It's possible the ubuntu runner is using some other shell. * Fix spec type errors * Switch to node for Windows compatibility --- .eslintignore | 2 ++ .../models/data/server-config.data.spec.ts | 17 ++++------- .../src/services/import.service.spec.ts | 5 ++-- package.json | 2 +- scripts/test-types.js | 29 +++++++++++++++++++ 5 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 scripts/test-types.js diff --git a/.eslintignore b/.eslintignore index f34b968315..e1fbda3813 100644 --- a/.eslintignore +++ b/.eslintignore @@ -27,3 +27,5 @@ apps/cli/config/config.js tailwind.config.js libs/components/tailwind.config.base.js libs/components/tailwind.config.js + +scripts/*.js diff --git a/libs/common/src/models/data/server-config.data.spec.ts b/libs/common/src/models/data/server-config.data.spec.ts index 1c4e890ab8..30dc46cf1b 100644 --- a/libs/common/src/models/data/server-config.data.spec.ts +++ b/libs/common/src/models/data/server-config.data.spec.ts @@ -7,7 +7,7 @@ import { describe("ServerConfigData", () => { describe("fromJSON", () => { it("should create a ServerConfigData from a JSON object", () => { - const serverConfigData = ServerConfigData.fromJSON({ + const json = { version: "1.0.0", gitHash: "1234567890", server: { @@ -22,18 +22,11 @@ describe("ServerConfigData", () => { sso: "https://sso.com", }, utcDate: "2020-01-01T00:00:00.000Z", - }); + featureStates: { feature: "state" }, + }; + const serverConfigData = ServerConfigData.fromJSON(json); - expect(serverConfigData.version).toEqual("1.0.0"); - expect(serverConfigData.gitHash).toEqual("1234567890"); - expect(serverConfigData.server.name).toEqual("test"); - expect(serverConfigData.server.url).toEqual("https://test.com"); - expect(serverConfigData.environment.vault).toEqual("https://vault.com"); - expect(serverConfigData.environment.api).toEqual("https://api.com"); - expect(serverConfigData.environment.identity).toEqual("https://identity.com"); - expect(serverConfigData.environment.notifications).toEqual("https://notifications.com"); - expect(serverConfigData.environment.sso).toEqual("https://sso.com"); - expect(serverConfigData.utcDate).toEqual("2020-01-01T00:00:00.000Z"); + expect(serverConfigData).toEqual(json); }); it("should be an instance of ServerConfigData", () => { diff --git a/libs/importer/src/services/import.service.spec.ts b/libs/importer/src/services/import.service.spec.ts index 9dafaed14f..6dd6438b01 100644 --- a/libs/importer/src/services/import.service.spec.ts +++ b/libs/importer/src/services/import.service.spec.ts @@ -62,8 +62,9 @@ describe("ImportService", () => { }); it("has the promptForPassword_callback set", async () => { - expect(importer.promptForPassword_callback).not.toBeNull(); - expect(await importer.promptForPassword_callback()).toEqual(password); + // Cast to any to access private property. Note: assumes instance of BitwardenPasswordProtectedImporter + expect((importer as any).promptForPassword_callback).not.toBeNull(); + expect(await (importer as any).promptForPassword_callback()).toEqual(password); }); it("has the appropriate organization Id", () => { diff --git a/package.json b/package.json index c701317cdb..3a29fa4ab7 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "test": "jest", "test:watch": "jest --clearCache && jest --watch", "test:watch:all": "jest --watchAll", - "test:types": "for p in libs/**/tsconfig.spec.json; do echo \"Typechecking $p\"; tsc --noEmit --project $p; done", + "test:types": "node ./scripts/test-types.js", "docs:json": "compodoc -p ./tsconfig.json -e json -d .", "storybook": "npm run docs:json && start-storybook -p 6006", "build-storybook": "npm run docs:json && build-storybook", diff --git a/scripts/test-types.js b/scripts/test-types.js new file mode 100644 index 0000000000..0fc27f3646 --- /dev/null +++ b/scripts/test-types.js @@ -0,0 +1,29 @@ +const concurrently = require("concurrently"); +const path = require("path"); +const fs = require("fs"); + +function getFiles(dir) { + results = []; + fs.readdirSync(dir).forEach((file) => { + file = path.join(dir, file); + const stat = fs.statSync(file); + if (stat && stat.isDirectory()) { + results = results.concat(getFiles(file)); + } else { + results.push(file); + } + }); + return results; +} + +const files = getFiles(path.join(__dirname, "..", "libs")).filter((file) => { + const name = path.basename(file); + return name === "tsconfig.spec.json"; +}); + +concurrently( + files.map((file) => ({ + name: path.basename(path.dirname(file)), + command: `npx tsc --noEmit --project ${file}`, + })) +); From 8e61184c0f8d94cdc0d0b33bd5668ce4cb473fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Tue, 16 May 2023 16:26:01 +0200 Subject: [PATCH 06/75] [PM-2197] Fix memory leaks in Safari (#5451) * Remove reference cycle between ThemingService and the global window object * Deregister messageListeners on a safari popup to avoid mem leaks * Use pagehide event instead of unload --- apps/browser/src/browser/browserApi.ts | 22 ++++++++++++++----- .../src/services/theming/theming.service.ts | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/apps/browser/src/browser/browserApi.ts b/apps/browser/src/browser/browserApi.ts index e93fcceb0d..b1313ebda6 100644 --- a/apps/browser/src/browser/browserApi.ts +++ b/apps/browser/src/browser/browserApi.ts @@ -168,15 +168,27 @@ export class BrowserApi { chrome.tabs.remove(tabToClose.id); } + private static registeredMessageListeners: any[] = []; + static messageListener( name: string, callback: (message: any, sender: chrome.runtime.MessageSender, response: any) => void ) { - chrome.runtime.onMessage.addListener( - (msg: any, sender: chrome.runtime.MessageSender, response: any) => { - callback(msg, sender, response); - } - ); + chrome.runtime.onMessage.addListener(callback); + + // Keep track of all the events registered in a Safari popup so we can remove + // them when the popup gets unloaded, otherwise we cause a memory leak + if (BrowserApi.isSafariApi && !BrowserApi.isBackgroundPage(window)) { + BrowserApi.registeredMessageListeners.push(callback); + + // The MDN recommend using 'visibilitychange' but that event is fired any time the popup window is obscured as well + // 'pagehide' works just like 'unload' but is compatible with the back/forward cache, so we prefer using that one + window.onpagehide = () => { + for (const callback of BrowserApi.registeredMessageListeners) { + chrome.runtime.onMessage.removeListener(callback); + } + }; + } } static sendMessage(subscriber: string, arg: any = {}) { diff --git a/libs/angular/src/services/theming/theming.service.ts b/libs/angular/src/services/theming/theming.service.ts index 270cd92c4f..fbae277cab 100644 --- a/libs/angular/src/services/theming/theming.service.ts +++ b/libs/angular/src/services/theming/theming.service.ts @@ -63,7 +63,7 @@ export class ThemingService implements AbstractThemingService { protected monitorSystemThemeChanges(): void { fromEvent( - this.window.matchMedia("(prefers-color-scheme: dark)"), + window.matchMedia("(prefers-color-scheme: dark)"), "change" ).subscribe((event) => { this.updateSystemTheme(event.matches ? ThemeType.Dark : ThemeType.Light); From cd6868feee36ec0f92d2a562ec7b6a7aaafa8a3a Mon Sep 17 00:00:00 2001 From: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Date: Tue, 16 May 2023 10:35:57 -0500 Subject: [PATCH 07/75] Hide +New Project on secret edit (#5370) --- .../secrets/dialog/secret-dialog.component.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts index 0e37471970..64b75511ff 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts @@ -68,6 +68,9 @@ export class SecretDialogComponent implements OnInit { throw new Error(`The secret dialog was not called with the appropriate operation values.`); } else if (this.data.operation == OperationType.Add) { await this.loadProjects(true); + if (this.data.projectId == null || this.data.projectId == "") { + this.addNewProjectOptionToProjectsDropDown(); + } } if (this.data.projectId) { @@ -78,10 +81,6 @@ export class SecretDialogComponent implements OnInit { this.formGroup.get("project").removeValidators(Validators.required); this.formGroup.get("project").updateValueAndValidity(); } - - if (this.data.projectId == null || this.data.projectId == "") { - this.addNewProjectOptionToProjectsDropDown(); - } } async loadData() { From 0d9345db8f1598b440b224660c5ba75eee257b86 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Tue, 16 May 2023 20:23:16 +0200 Subject: [PATCH 08/75] [PM-2194] Tweak the CL search inputs reset button (#5409) --- .../src/search/close-button-white.svg | 3 +++ .../src/search/search.component.css | 19 +++++++++++++++++++ libs/components/src/tw-theme.css | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 libs/components/src/search/close-button-white.svg create mode 100644 libs/components/src/search/search.component.css diff --git a/libs/components/src/search/close-button-white.svg b/libs/components/src/search/close-button-white.svg new file mode 100644 index 0000000000..8eff9f53f3 --- /dev/null +++ b/libs/components/src/search/close-button-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/libs/components/src/search/search.component.css b/libs/components/src/search/search.component.css new file mode 100644 index 0000000000..87c38348bc --- /dev/null +++ b/libs/components/src/search/search.component.css @@ -0,0 +1,19 @@ +/** + * Tailwind doesn't have a good way to style search-cancel-button. + */ +bit-search input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; + appearance: none; + height: 21px; + width: 21px; + margin: 0; + cursor: pointer; + background-repeat: no-repeat; + mask-image: url("./close-button-white.svg"); + -webkit-mask-image: url("./close-button-white.svg"); + background-color: rgba(var(--color-text-muted)); +} + +bit-search input[type="search"]::-webkit-search-cancel-button:hover { + background-color: rgba(var(--color-text-main)); +} diff --git a/libs/components/src/tw-theme.css b/libs/components/src/tw-theme.css index f5d9febceb..ba4efe60e7 100644 --- a/libs/components/src/tw-theme.css +++ b/libs/components/src/tw-theme.css @@ -79,3 +79,5 @@ --tw-ring-offset-color: #1f242e; } + +@import "./search/search.component.css"; From aa2da5713962fa9e19b9f7730cd9a532796ae8d1 Mon Sep 17 00:00:00 2001 From: Cesar Gonzalez Date: Tue, 16 May 2023 18:00:09 -0500 Subject: [PATCH 09/75] [PM-595] Autofill doesn't work for logins without passwords (#5325) --- apps/browser/src/autofill/services/autofill.service.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index 8a4046f59c..090acf35dc 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -373,12 +373,6 @@ export default class AutofillService implements AutofillServiceInterface { fillScript.untrustedIframe = this.inUntrustedIframe(pageDetails.url, options); - if (!login.password || login.password === "") { - // No password for this login. Maybe they just wanted to auto-fill some custom fields? - fillScript = AutofillService.setFillScriptForFocus(filledFields, fillScript); - return fillScript; - } - let passwordFields = AutofillService.loadPasswordFields( pageDetails, false, From 3da7fc7cb39f575a96c52a6a17a4eba8cf651093 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Wed, 17 May 2023 12:27:27 +0200 Subject: [PATCH 10/75] Deprecated broadcaster (#5461) --- apps/desktop/src/app/app.component.ts | 6 ++++++ apps/web/src/app/app.component.ts | 6 ++++++ libs/common/src/abstractions/broadcaster.service.ts | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index c87a2eacfc..835b568c8c 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -156,6 +156,12 @@ export class AppComponent implements OnInit, OnDestroy { window.onkeypress = () => this.recordActivity(); }); + /// ############ DEPRECATED ############ + /// Please do not use the AppComponent to send events between services. + /// + /// Services that depends on other services, should do so through Dependency Injection + /// and subscribe to events through that service observable. + /// this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => { this.ngZone.run(async () => { switch (message.command) { diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index e3e93840e1..feea3c5de8 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -98,6 +98,12 @@ export class AppComponent implements OnDestroy, OnInit { window.onkeypress = () => this.recordActivity(); }); + /// ############ DEPRECATED ############ + /// Please do not use the AppComponent to send events between services. + /// + /// Services that depends on other services, should do so through Dependency Injection + /// and subscribe to events through that service observable. + /// this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => { this.ngZone.run(async () => { switch (message.command) { diff --git a/libs/common/src/abstractions/broadcaster.service.ts b/libs/common/src/abstractions/broadcaster.service.ts index 9d080d0363..5df3c03343 100644 --- a/libs/common/src/abstractions/broadcaster.service.ts +++ b/libs/common/src/abstractions/broadcaster.service.ts @@ -2,8 +2,20 @@ export interface MessageBase { command: string; } +/** + * @deprecated Use the observable from the appropriate service instead. + */ export abstract class BroadcasterService { + /** + * @deprecated Use the observable from the appropriate service instead. + */ send: (message: MessageBase, id?: string) => void; + /** + * @deprecated Use the observable from the appropriate service instead. + */ subscribe: (id: string, messageCallback: (message: MessageBase) => void) => void; + /** + * @deprecated Use the observable from the appropriate service instead. + */ unsubscribe: (id: string) => void; } From 3f7a63b2c6789b263b29421776aa77be07b9e384 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Thu, 18 May 2023 10:32:18 -0700 Subject: [PATCH 11/75] [PM-2102] Implement logic to keep row control enable/disable status in sync with the access item properties whenever the parent control is enabled/disabled (#5433) Angular 15 introduced a breaking change that calls setDisabledState() whenever a CVA is added. This was re-enabling all the internal form group rows (even those that should have remained disabled). --- .../access-selector.component.ts | 73 +++++++++++++------ libs/angular/src/utils/form-selection-list.ts | 14 ++++ 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts index 7767953b30..d268a6ca5e 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts @@ -1,7 +1,14 @@ import { Component, forwardRef, Input, OnDestroy, OnInit } from "@angular/core"; -import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from "@angular/forms"; +import { + ControlValueAccessor, + FormBuilder, + FormControl, + FormGroup, + NG_VALUE_ACCESSOR, +} from "@angular/forms"; import { Subject, takeUntil } from "rxjs"; +import { ControlsOf } from "@bitwarden/angular/types/controls-of"; import { FormSelectionList } from "@bitwarden/angular/utils/form-selection-list"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { SelectItemView } from "@bitwarden/components/src/multi-select/models/select-item-view"; @@ -47,6 +54,40 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On private notifyOnTouch: () => void; private pauseChangeNotification: boolean; + /** + * Updates the enabled/disabled state of provided row form group based on the item's readonly state. + * If a row is enabled, it also updates the enabled/disabled state of the permission control + * based on the item's accessAllItems state and the current value of `permissionMode`. + * @param controlRow - The form group for the row to update + * @param item - The access item that is represented by the row + */ + private updateRowControlDisableState = ( + controlRow: FormGroup>, + item: AccessItemView + ) => { + // Disable entire row form group if readonly + if (item.readonly) { + controlRow.disable(); + } else { + controlRow.enable(); + + // The enable() above also enables the permission control, so we need to disable it again + // Disable permission control if accessAllItems is enabled or not in Edit mode + if (item.accessAllItems || this.permissionMode != PermissionMode.Edit) { + controlRow.controls.permission.disable(); + } + } + }; + + /** + * Updates the enabled/disabled state of ALL row form groups based on each item's readonly state. + */ + private updateAllRowControlDisableStates = () => { + this.selectionList.forEachControlItem((controlRow, item) => { + this.updateRowControlDisableState(controlRow as FormGroup>, item); + }); + }; + /** * The internal selection list that tracks the value of this form control / component. * It's responsible for keeping items sorted and synced with the rendered form controls @@ -55,21 +96,13 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On protected selectionList = new FormSelectionList((item) => { const permissionControl = this.formBuilder.control(this.initialPermission); - const fg = this.formBuilder.group({ - id: item.id, - type: item.type, + const fg = this.formBuilder.group>({ + id: new FormControl(item.id), + type: new FormControl(item.type), permission: permissionControl, }); - // Disable entire row form group if readonly - if (item.readonly) { - fg.disable(); - } - - // Disable permission control if accessAllItems is enabled - if (item.accessAllItems || this.permissionMode != PermissionMode.Edit) { - permissionControl.disable(); - } + this.updateRowControlDisableState(fg, item); return fg; }, this._itemComparator.bind(this)); @@ -124,14 +157,8 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On set permissionMode(value: PermissionMode) { this._permissionMode = value; - // Toggle any internal permission controls - for (const control of this.selectionList.formArray.controls) { - if (value == PermissionMode.Edit) { - control.get("permission").enable(); - } else { - control.get("permission").disable(); - } - } + // Update any internal permission controls + this.updateAllRowControlDisableStates(); } private _permissionMode: PermissionMode = PermissionMode.Hidden; @@ -189,6 +216,10 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On this.formGroup.disable(); } else { this.formGroup.enable(); + + // The enable() above automatically enables all the row controls, + // so we need to disable the readonly ones again + this.updateAllRowControlDisableStates(); } } diff --git a/libs/angular/src/utils/form-selection-list.ts b/libs/angular/src/utils/form-selection-list.ts index 026ef367a4..aa454e81e4 100644 --- a/libs/angular/src/utils/form-selection-list.ts +++ b/libs/angular/src/utils/form-selection-list.ts @@ -198,4 +198,18 @@ export class FormSelectionList< this.selectItem(selectedItem.id, selectedItem); } } + + /** + * Helper method to iterate over each "selected" form control and its corresponding item + * @param fn - The function to call for each form control and its corresponding item + */ + forEachControlItem( + fn: (control: AbstractControl, TControlValue>, value: TItem) => void + ) { + for (let i = 0; i < this.formArray.length; i++) { + // The selectedItems array and formArray are explicitly kept in sync, + // so we can safely assume the index of the form control and item are the same + fn(this.formArray.at(i), this.selectedItems[i]); + } + } } From 3577b7c1009f8373b55acbb00f28e9f91a9ddb02 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Thu, 18 May 2023 13:35:13 -0400 Subject: [PATCH 12/75] [PM-1072] Convert autofill.js to Typescript (#5376) * Rename autofill.js to ts and update webpack * Remove wrapping function * Remove unreachable data-onepassword-title code * Remove unused post-submit logic * Run prettier * Remove unused fake tested code * Add typing * Disable certain eslint rules or fix eslint violations * Update modifications list * Remove unnecessary/confusing types * Checkout autofill.js from master * Add ENV switch for autofill versions * Rename autofill.ts to avoid confusion * Use string union type for FillScriptOp --- apps/browser/package.json | 1 + .../src/autofill/content/autofillv2.ts | 1391 +++++++++++++++++ .../src/autofill/models/autofill-script.ts | 27 +- apps/browser/webpack.config.js | 11 +- 4 files changed, 1423 insertions(+), 7 deletions(-) create mode 100644 apps/browser/src/autofill/content/autofillv2.ts diff --git a/apps/browser/package.json b/apps/browser/package.json index 0057704287..b29ab9c27b 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -6,6 +6,7 @@ "build:mv3": "cross-env MANIFEST_VERSION=3 webpack", "build:watch": "webpack --watch", "build:watch:mv3": "cross-env MANIFEST_VERSION=3 webpack --watch", + "build:watch:autofill": "cross-env AUTOFILL_VERSION=2 webpack --watch", "build:prod": "cross-env NODE_ENV=production webpack", "build:prod:watch": "cross-env NODE_ENV=production webpack --watch", "dist": "npm run build:prod && gulp dist", diff --git a/apps/browser/src/autofill/content/autofillv2.ts b/apps/browser/src/autofill/content/autofillv2.ts new file mode 100644 index 0000000000..8bf16ff879 --- /dev/null +++ b/apps/browser/src/autofill/content/autofillv2.ts @@ -0,0 +1,1391 @@ +/* eslint-disable no-var, no-console, no-prototype-builtins */ +// These eslint rules are disabled because the original JS was not written with them in mind and we don't want to fix +// them all now + +/* + 1Password Extension + + Lovingly handcrafted by Dave Teare, Michael Fey, Rad Azzouz, and Roustem Karimov. + Copyright (c) 2014 AgileBits. All rights reserved. + + ================================================================================ + + Copyright (c) 2014 AgileBits Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +/* + MODIFICATIONS FROM ORIGINAL + + 1. Populate isFirefox + 2. Remove isChrome and isSafari since they are not used. + 3. Unminify and format to meet Mozilla review requirements. + 4. Remove unnecessary input types from getFormElements query selector and limit number of elements returned. + 5. Remove fakeTested prop. + 6. Rename com.agilebits.* stuff to com.bitwarden.* + 7. Remove "some useful globals" on window + 8. Add ability to autofill span[data-bwautofill] elements + 9. Add new handler, for new command that responds with page details in response callback + 10. Handle sandbox iframe and sandbox rule in CSP + 11. Work on array of saved urls instead of just one to determine if we should autofill non-https sites + 12. Remove setting of attribute com.browser.browser.userEdited on user-inputs + 13. Handle null value URLs in urlNotSecure + 14. Convert to Typescript, add typings and remove dead code (not marked with START/END MODIFICATION) + */ +import AutofillForm from "../models/autofill-form"; +import AutofillPageDetails from "../models/autofill-page-details"; +import AutofillScript, { + AutofillScriptOptions, + FillScript, + FillScriptOp, +} from "../models/autofill-script"; + +/** + * The Document with additional custom properties added by this script + */ +type AutofillDocument = Document & { + elementsByOPID: Record; + elementForOPID: (opId: string) => Element; +}; + +/** + * A HTMLElement (usually a form element) with additional custom properties added by this script + */ +type ElementWithOpId = T & { + opid: string; +}; + +/** + * This script's definition of a Form Element (only a subset of HTML form elements) + * This is defined by getFormElements + */ +type FormElement = HTMLInputElement | HTMLSelectElement | HTMLSpanElement; + +/** + * A Form Element that we can set a value on (fill) + */ +type FillableControl = HTMLInputElement | HTMLSelectElement; + +function collect(document: Document) { + // START MODIFICATION + var isFirefox = + navigator.userAgent.indexOf("Firefox") !== -1 || navigator.userAgent.indexOf("Gecko/") !== -1; + // END MODIFICATION + + (document as AutofillDocument).elementsByOPID = {}; + + function getPageDetails(theDoc: Document, oneShotId: string) { + // start helpers + + /** + * For a given element `el`, returns the value of the attribute `attrName`. + * @param {HTMLElement} el + * @param {string} attrName + * @returns {string} The value of the attribute + */ + function getElementAttrValue(el: any, attrName: string) { + var attrVal = el[attrName]; + if ("string" == typeof attrVal) { + return attrVal; + } + attrVal = el.getAttribute(attrName); + return "string" == typeof attrVal ? attrVal : null; + } + + /** + * Returns the value of the given element. + * @param {HTMLElement} el + * @returns {any} Value of the element + */ + function getElementValue(el: any) { + switch (toLowerString(el.type)) { + case "checkbox": + return el.checked ? "✓" : ""; + + case "hidden": + el = el.value; + if (!el || "number" != typeof el.length) { + return ""; + } + 254 < el.length && (el = el.substr(0, 254) + "...SNIPPED"); + return el; + + default: + // START MODIFICATION + if (!el.type && el.tagName.toLowerCase() === "span") { + return el.innerText; + } + // END MODIFICATION + return el.value; + } + } + + /** + * If `el` is a ` - +
- diff --git a/apps/browser/src/auth/popup/home.component.ts b/apps/browser/src/auth/popup/home.component.ts index 9f864fa2ad..361218c6e4 100644 --- a/apps/browser/src/auth/popup/home.component.ts +++ b/apps/browser/src/auth/popup/home.component.ts @@ -1,7 +1,9 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; -import { ActivatedRoute, Router } from "@angular/router"; +import { Router } from "@angular/router"; +import { Subject, takeUntil } from "rxjs"; +import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component"; import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; @@ -12,9 +14,12 @@ import { LoginService } from "@bitwarden/common/auth/abstractions/login.service" selector: "app-home", templateUrl: "home.component.html", }) -export class HomeComponent implements OnInit { - loginInitiated = false; +export class HomeComponent implements OnInit, OnDestroy { + @ViewChild(EnvironmentSelectorComponent, { static: true }) + environmentSelector!: EnvironmentSelectorComponent; + private destroyed$: Subject = new Subject(); + loginInitiated = false; formGroup = this.formBuilder.group({ email: ["", [Validators.required, Validators.email]], rememberEmail: [false], @@ -27,9 +32,9 @@ export class HomeComponent implements OnInit { private router: Router, private i18nService: I18nService, private environmentService: EnvironmentService, - private route: ActivatedRoute, private loginService: LoginService ) {} + async ngOnInit(): Promise { let savedEmail = this.loginService.getEmail(); const rememberEmail = this.loginService.getRememberEmail(); @@ -48,6 +53,18 @@ export class HomeComponent implements OnInit { }); } } + + this.environmentSelector.onOpenSelfHostedSettings + .pipe(takeUntil(this.destroyed$)) + .subscribe(() => { + this.setFormValues(); + this.router.navigate(["environment"]); + }); + } + + ngOnDestroy(): void { + this.destroyed$.next(); + this.destroyed$.complete(); } submit() { diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index a0cd5e8887..3b8501be44 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -10,6 +10,7 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { BrowserModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component"; import { BitwardenToastModule } from "@bitwarden/angular/components/toastr.component"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { ColorPasswordCountPipe } from "@bitwarden/angular/pipes/color-password-count.pipe"; @@ -153,6 +154,7 @@ import "./locales"; AboutComponent, HelpAndFeedbackComponent, AutofillComponent, + EnvironmentSelectorComponent, ], providers: [CurrencyPipe, DatePipe], bootstrap: [AppComponent], diff --git a/apps/browser/src/popup/images/eu-flag.png b/apps/browser/src/popup/images/eu-flag.png new file mode 100644 index 0000000000000000000000000000000000000000..592bc95e0ce80551d890e7867335df7c8206ccdb GIT binary patch literal 4549 zcmZ`+2Q*w;)E+@}MsLCB-OLz78H4DeMf4JN^wGsAF;31hbN6@m{=U8UIp?ms){WEGRi_|jAq4;c6q*_;1{ap$Vp0)b zy|~Yz6r2G7a(NeJWqnO$Wsts)r=yEI5&+PM%P=7_z1_=@XOWhwc!NYmQENp9xT>l} zEE*AJ*si8=C5px#6#H>lm2gsw%SPEmmClL`MWEpWoRReFOoZdG$nk3Bv?Nvj_U=`yg}$ zqTzTqnhc{y>97XTx9N_;run3@D7;|+Ay>-^9twcD@EB|l?UEWfK~z;33#P*>7>xRO zT`pLbW8NY5)zc& z=$$8}ca0()O~G9Et^sfRu-3`^Mo#;VoyF+=9AaL?<7{@;@*b**{)P7oG4}1|gj~kc zpcIgk-O-%sQA8W)-N!1AZ~-y3-aVxpR^Y3Zgxhb;ZfONi8>Z58jb`82NK0od+(_vD z)*M0k4!>y`#>75AjEv$el{748$`4I$!gwtt}KBg28t1PZ>VQdjJkHBNpP-FoD zf{Pt1)gziz3G$%@fL|mJ0E^^5$WrS`71_ryY$HN>2Oy&_S^V1%Nb+vvP;@9Vgk-)C zj*D)37s;>B{VOIwjE+6=I$8Y7)7f>R+F41FQW6u_qDb~9YmtxMg6u%hhfLZv?LWM& zr&+0D^e_UtSfVW%>E!K$sOM2q9rhhMH{`xW;wP3Cn5$?C0#;~?iSu4A!-{mP>q;|l(`SCqZ!Xj%O zm>@E#u&hq)_FlhbN?Ek?v>MZc;Fz%O6s;=$$hiT(%Yut#>s-U5m5YYW4OPg2#7s4$V%#*cchb+dG{cZ1{WER|Z^Q?72T&YRKLng@xc6P^=a;ZuL> z%k<9A$Is`A;sNHCyR|3N?)lXY?7me!afLU>a9dkj)pld09^jf(cwg%&Zg7odnr{wq z&sI`TsQ31Y*Hk1RfW#j=vL8kb!JqJg>$Xv#@i9Pxu5b+?8BMz((>>XoZ!{3vempWI zY5}|#Z9)2!bzz$}*FO?bMg)10=Un~Ph8!aGh&b^&@C#=wplZU;rzYU!G>l4K;p~bf zw2P7EWRC^YL`88AYjC9{7IAW^#P=&PaPs!B6kVH&Hso&QQhzYoqgq7Kkl+WB?{QnC zjeqJ|D&-n${;cp8)x-PIPpekwBq(yj8441H>7AL)?{BHD4~?!M_xV00w7qq9@2j}$Rl;6I>z6T!p zG+mobn*2I&TvuD z<)j@KG*UVnn}dzR=A+|3s%`Kbq-*fVr?K_M&}q)6`Dm&ZB^5Onr5CvsiH#7^8`0a- z^Jmy(@X$Zdda70So;`zBXwopREQHT3RkY{MqK0@rJfSJADRNq)MQe)-Q{rs!QULML zRO>2|vpCV;GFc^~(niHv?H^%lgyWRsDX!+Ob*}EUy{-ne^scxu z-Le^@VC7;1(Xz8K9#=7c!rH8$=;PSqaJA<$L(&om6yjBcu{usIxJ=i$Uf-!q&j_p! zHc}`GHEK4Ad}&+OJ~8LoKUz8@UG8mBXq{dmqXsj8S@&6x9u-h2fTZJDrp zwQ25DBfH8plQ>wix00|Tx8k&F^+^RKj7q*6eK+m^vB|KBU=w9y%thyh6EW8_<*P9z+av)KO{JdQeOpVt?XSLeyiV$u;D5OOW$d)5dyH(PZ_MJA z$?HRXj>-D*`~rpBnCdgL(=QJ`aW|{)sxhR%rFZl2Ty5NdD9C3UTswVas4{maP`T=> zS|=>JS&f_+cj9ch5CTH_LCR`ib6?S(aQr6zO4LXIN!m6&bW>s;_yYU1@1& z<~fBbc6(PPR9RjXWTR7iP@QLMg}m1p?Yv-{?o!=bGR{!zU#nC9s#D|uymd^06z%Bh1{q65QH9uF1hF_@XbDRzgk3;*sV-`-K z=Js7lg4af+muu5s(S9iFSdE5_%X|!M@r~RQW|U(L?{mzQtMHrLskmvGZQ0t`fYY3I zoe7#Am`R@zp79KJ4ps>iImFIsekcE)vmMyKSD2Y?QZcFYy0vMu8P5{2ca(LO8NE^M`mFRFTGuXHNce zf_&yZAs`t!i3p`T$p~pYnGjVFojXeogC*@W<2;MF+@hfXr-X=~{|YLZGp4(2c|XaQ z<9dLl?_+aQZPUPy3tpeSG|>xazhBrLw{C^l%2=T4n0kbU?&7DOm|MoTV9!Fc6?1@+ zPwhHJSD?eb&pvby*_XWAhzn$71>(dHLUa6cBq{{&$cOrb`2RYIYKxL2*`!t1%aPmh zc^3K%QpFkfkS@OlR)#ScD*BP$$cNJv%L;LeAAk5ukn#DN-auARNY=5$R*iCR)MC`4 ze6Kb3!L*PEhLpcpyf~$M88z2Dcd|FR6HI`Jkc@CDLzKB0;6_76CQ5!3ofK!59Fk6T z__-f8nd6WsLjmgdQ+eDAc3j zn|cztsNL(*GagO!Q`o?5Rc|C2KHC)EL_0oy3ov^jP%W2Q? z`T+DvwU=(U<-{~qLC-)OkK~5Gub&W!OQCZ^h1fpE0Ibmj|qEi%k9W&vZ69*;<(y7~dKn4<97gF6}g0{jg5OwwjvZ_Xbc8E&uEjOOZ$W^Ls^K`*QAMJ+$7 zwsivMkRbw=;p@M8$qu_-O`m4UrC1<5)>f3K-?}b|b zQrhm^N@3^tfYCbI-`ML17lD!1s1~VEvXcWFP_T_+e}>nRIvzP`Ru*a7x)ng57O$Z5 zgc+GOf5s1vogWlZpHr}X$9C(^G@$f;#s<>|1YsMVz#}ryb-F2P!~{pd;GnWN+9Z8e z7{1=OR&D!nmGF6e*%p()pXR+0SH}S zVgMl?4FLZF;ayw+JQe`qZwvrv;j#XW4e$j1aIOFVF)jdtKOFN5dpR^N=7su?y;5-H zZw5mF{@;7pJiPv z5PTT{L&YHA|B@lmF8`10GV+(~_qzTn2fs`vtLNi_ylD8cEd&()yTJeP{nH-&GK;Lf z3mWNes^Wq|diY*y#32wk_&+26sWkgX35CJ_t^8Nyj}i{P+^2u-+h2$B+k0^;2vRus z?-NFlGJ*A9T)Yoinkq_$($xNjI&QSL=;YHi`Ji#VkBdfC%v)258}&uh$_sE<6U(v} z&o(hYOr(W{0P)sX^SmxEfr1hvp}i4Jg662iL`l-7!b6p0nU?VcP{W0i;ryx%hG`6o#A3qY2M76Bk?nHpu4EVKImNz%i$X~zWMH#A-$)tU_U|!y~Homj%@nwB{L6UWvmD-N=QGKG*G(Bk?!+=r)AQ@ zbR3p#ZihPpl2gB*r+n~!sDk@U%11%AG;3JH9`=C7+5D`KMTuxY>MIFrIuXJ90njsB zBC7yTK{2r2qX&`P)He`B-U}V#?6a0dR$;oWnEstbWHMwKlIi9k>Vm$Ozrcj5ZYZ9c zcc#inj;Hs@xJfn^tnv-vJtV>Cqi<~lz45%4pFk@KXh%(yEysqV=h3>y^8B0OF|e!I z4!@pXuJm=O2Enz(6_*{2q2#U9BwD`(Ix`x|9; zV})+hMCtw|mI^jK9hlfs?frt=V8(K0_zRcExE7wTa(Z1}Wm#%zmB@KW!0V5rP}(I`pV`pV z(MTz=l;PI!`6UD5BULuI5RlvXdk4?cb7rA_>EJ0nmXIk{){1KMG@i9~OxhRar%M$_ ZL?0{(q>lp{lP?@ppeT!2RtK#pA#Ml+ z2kNvat6mGGumVSn4=Uk~39_0i=qXW|5P=<()&+wbAQ9Z$YnCmg^=d$qgXdfQhw0K6 zG9F8JYzNX)q;Ud&@s#RgpP&E<0w13%hF^zradHZ&X##N*03>z*-sEI98zrSDIQn>N zP03z00M^%Ur+RD8C(g~HIn5HGPQdc%&O01SsFe-CaT_i$Q&A9XL3DoY>; zC||D=HcVBk9rl3gC~%rnES1Df1i*_jE@dYH81j7)*~Qo=gpA^s=SD!NfLQ~fmr0+^Cw^2kH zeqg_CC}#7rMmlA<&03#i-t;~~k-gmz6ad=!egMjShPJoEwlay%eJ`^Z0N_}vz{R1& zmN*e1N(SWL5RVbX(3dzuSQfiRXfh>HxnTQUTuC`0L|RGW${@nb&ZIcBUwake%HiH5 zY!;uF;>OQ$v4#e!^u!Mm4p~ux3uGNLxMJc1U*eT3XxQ9)Ib`D~Cnat9S(!EVMTZNi zTcs=&Mb=!`jy6ZjAmU_x9ow>PX*B!1Xm_(bq9^Lh$m7r*@ z>p{o+`{hv*+rh+}wcJXuBVG{cI2Z&CqCyb9Boz)U%dcsqZR9Zw2GXj^GJpWS`8H)L z!SzblGljAMrvy&{i^Tgx2{nYWOkV;Rhj=p%zz@Hsa&0{&$dJd9w93->C4cmd46E-5 z;nHF|4fhhHVu}$bih6T4yM|viE6V?hKo6A{!j!Ta@}eDV2^M-rcdxQ#-_30LCRw;< z0Jlah{-&fv+}1&8VW?QERjazZ^ta917TMPN&lcpQ7s+&&Sig4}&%H<(rY38C43@U; zq_2gSb(v%_(`@3))X57N(bw?v^;t{@+-xB;Q?OTg#GboIZXNJ$|7XT+qtrD}H2>J0 zB^7dqk6Mir3Ic6s6#?CF=243_f%5!umUY-8hPnvGwpAddbfl=cUfF^$>~>v7x9wO~ zjh#0vB|+tgEFi>8_eIaGE`~0qE=W|hv0S5LJl^`sya9!Up^sn^?!}F3oGR@ebRB4S zwEH#LgMj;vW-fF)7kI6;dnPqEO5Kd2od^MV5qQ=P?FEuUaYkKX8qFjaoB+`E&LC9~5k-p*-D4^24+o%N*vFL^i}#}$`I*o;_{8-99YmW&R*#cOew~FyCp2!Er85H8GF*a% zDFQ+f8p<}P%98!qLr;cWWX{hpmZK<>_#@QXa|sXf#-++hLJ1DjW4m z3>9IRlY5`+*^{vB@@1;qBkcJzi%HkH;s4=*G4I49#8Wlw|xi!6!zu2*!y zpkg$U92P|{ucw7mTjlFh>qd*VZuv1fborFWOOO{X+?!?^nA3uh{`e;H)BDK1{?=^l z*th;8&w8A#wkGmd*KvXwTcVp;?y={Q+fYQ^$PY~qWecrv74RhgN*<|*HyE`{I%df# z6e5vUi>-~U&BR2FE3dO3B&o8?Br^7dQ>o1-x~nPW#pX5SCFMEf2@c^?Kcu#z=6Y`a zoSph9A{$Zkk?A=l@0diQ8e?= zS0P_ppy>PyJ4({rCEAmu{I&l0!cPVkaoU6ndz-y#j&8ZFx*&4&;z$iq8% z{tp}ULf%*uwT#Z8`i5V9mMC^J$~8+Wl~fkd7BTX8zr@rZojPO4E^xO5EYLV=S+Zeh zTPd|dHxn~Zu)7?+EWK>IVlt`d#OD0epjI1I{SGNSlsH_e&>CUy#}$joZQ12I`61}&F zTFhfLBbixu9t2dJ8=QT8I?2|cvZG8B50lu*0HVwtKu*vp^ST!55Pt=>HjqO3H{~{w zum)vfwt!sXTu)`L7@wGx&c;sp1mou>0@0_bjw1F#$Brl@ zgRP<6huOVs`i{Of{t?G?gCv8@_vOc!UCAZUr9=L18YY?*nw$IsM)ft7@9vcuTN=1b zIORKZl=GGqm;0EjR~=MjSePImw}sg)SR~n3^c0NHRC!jZ*OZhspu#8LPY`T~O;p9Q z#_ZhUV0b9HTHTN;(+mI9*xA??^bNGBwXC)E)4lR|IdAZ_N+$DJ|KNyFuUq)SnUJAX zXDrXHVTq-xq!P+cMXf7gA|sOH-i;n1yL`0Lv_ZW#$P{z4;Go=hS`@|HN*2_wD8;r|FfB$-Ql=-)InNIK+6xS26I>)mb?f z#ut%|*`{gML59UAyk5K1WkxcOz5TdV-js4@HlXlA28_kzArFW|1r7kur?|*M*Y^e&VTY(biQD|k(id4s(5AclVnlH z+q1Q(h2)*Roiu77^$8ydZ}P*&+4fnqQ^m#7q(GPvqS|kgciP9+sJr?DZ*TF?M*D{M zROV*HtlK$lyjii=>K6aRv1hWK-pS_jO#jH{$cQiT!J9X74tb(7zFb>QGqkmDvqu{r zP5F18C*sTn?lte4B?UBiLf6fQS>hF{!Uah6n6jC9N)=XZM)pSv$7;mc#VQ#Yy()_a z>$baHNSijKY~0_>*A8qy=i=s~$)uAoaD8|2>_}&8rE)l3eK>V9GX=Axyc@doqQb%! zf+d1`Ey31Kdx+q)aVC2oFnftz`M-Ldlh;aXO(l2g*0xj(rwvz2KbSe$?K?U--kf?g zpE_GLJcjc&v##a6+p$f1f3=ZY&E|B5U)>q$g~s8`o4U7~-)Bzz0$OldL*~O7$nG-J z!-{{kEybU0IB#@GUz09{#d-TRC5;`=s|_SUOrkTjGhe_({B>tGzC3=zRa>}!ocF^7 z(hh+i(wr3?+kU^hmK=VubFqe)ZEq~qOVq=8o7^<$Td`KsJ5_N0>Re^(-Rxt3vs1aP zw#|4Z=1&2LqrLUrK1dz}Y39@@=1+8TU=H>*m+gD*`dtM`OqiNV*t})}(4qupwVlu- z6X(ylAQAHeyee~dEIJtPn@$5>J$b%P_X&>M4CH=61Qw^7Acv1KXAKM}2xIh;X8Dj$ zZfpUKaFENJlRQMtWjVDT=b*!%4Bh%B%|Cycu{8Q>39brbF8?PmNPRUMb#(ymCB6Z` z1yTTTE)nqZ0st8RxW6#~fB@e78*2l(|8TAW0O9t4>wh?gm-cF?Ud~JPAA2q9+TRSC zES$eF*%h^)jg9Wo5V)!ucmM!Ilvfi7NX1?{ui@J3=%e-3?@3v?I0;%m zDgX>4bqSr2XbUjL$;*JE12|@*-tZ+gw z7z}f_wvp0SRQ@Bse3D_cL!(`#AP_GvFF`L6K^J#hh>)bDBm^o95f&D>WC(b8JEJWy z0?r<6evUD|dTWw7rWn_$sf3rHdz8hL!cI(BI>)KGF6z|5S4J__M6b1wyVO z5FtS*vQQgd|D}A-5v8&2PF#P>n(c1S3jR6|o z%xYUz%HF z2jzg~#!N$-#VgQJ$InTtNe^CM)IZ|ubcHH|@GNOLw)EqSn!N{3_qOSirG2w%d%F4w zj*akQJB#ejgxY - +
-
+
Bitwarden

{{ "loginOrCreateNewAccount" | i18n }}

@@ -37,9 +25,7 @@ />
- +
+ + +
+ +
+
diff --git a/libs/angular/src/auth/components/environment-selector.component.ts b/libs/angular/src/auth/components/environment-selector.component.ts new file mode 100644 index 0000000000..c708a0af0e --- /dev/null +++ b/libs/angular/src/auth/components/environment-selector.component.ts @@ -0,0 +1,103 @@ +import { animate, state, style, transition, trigger } from "@angular/animations"; +import { ConnectedPosition } from "@angular/cdk/overlay"; +import { Component, EventEmitter, OnDestroy, OnInit, Output } from "@angular/core"; +import { Router } from "@angular/router"; +import { Subject } from "rxjs"; + +import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction"; +import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; + +@Component({ + selector: "environment-selector", + templateUrl: "environment-selector.component.html", + animations: [ + trigger("transformPanel", [ + state( + "void", + style({ + opacity: 0, + }) + ), + transition( + "void => open", + animate( + "100ms linear", + style({ + opacity: 1, + }) + ) + ), + transition("* => void", animate("100ms linear", style({ opacity: 0 }))), + ]), + ], +}) +export class EnvironmentSelectorComponent implements OnInit, OnDestroy { + @Output() onOpenSelfHostedSettings = new EventEmitter(); + isOpen = false; + showingModal = false; + selectedEnvironment: ServerEnvironment; + ServerEnvironmentType = ServerEnvironment; + euServerFlagEnabled: boolean; + overlayPostition: ConnectedPosition[] = [ + { + originX: "start", + originY: "bottom", + overlayX: "start", + overlayY: "top", + }, + ]; + protected componentDestroyed$: Subject = new Subject(); + + constructor( + protected environmentService: EnvironmentService, + protected configService: ConfigServiceAbstraction, + protected router: Router + ) {} + + async ngOnInit() { + this.euServerFlagEnabled = await this.configService.getFeatureFlagBool( + FeatureFlag.DisplayEuEnvironmentFlag + ); + this.updateEnvironmentInfo(); + } + + ngOnDestroy(): void { + this.componentDestroyed$.next(); + this.componentDestroyed$.complete(); + } + + async toggle(option: ServerEnvironment) { + this.isOpen = !this.isOpen; + if (option === ServerEnvironment.EU) { + await this.environmentService.setUrls({ base: "https://vault.bitwarden.eu" }); + } else if (option === ServerEnvironment.US) { + await this.environmentService.setUrls({ base: "https://vault.bitwarden.com" }); + } else if (option === ServerEnvironment.SelfHosted) { + this.onOpenSelfHostedSettings.emit(); + } + this.updateEnvironmentInfo(); + } + + updateEnvironmentInfo() { + const webvaultUrl = this.environmentService.getWebVaultUrl(); + if (this.environmentService.isSelfHosted()) { + this.selectedEnvironment = ServerEnvironment.SelfHosted; + } else if (webvaultUrl != null && webvaultUrl.includes("bitwarden.eu")) { + this.selectedEnvironment = ServerEnvironment.EU; + } else { + this.selectedEnvironment = ServerEnvironment.US; + } + } + + close() { + this.isOpen = false; + this.updateEnvironmentInfo(); + } +} + +enum ServerEnvironment { + US = "US", + EU = "EU", + SelfHosted = "Self-hosted", +} diff --git a/libs/angular/src/components/environment.component.ts b/libs/angular/src/components/environment.component.ts index 347b5686e7..f47fcf9124 100644 --- a/libs/angular/src/components/environment.component.ts +++ b/libs/angular/src/components/environment.component.ts @@ -4,6 +4,8 @@ import { EnvironmentService } from "@bitwarden/common/abstractions/environment.s import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; +import { ModalService } from "../services/modal.service"; + @Directive() export class EnvironmentComponent { @Output() onSaved = new EventEmitter(); @@ -19,7 +21,8 @@ export class EnvironmentComponent { constructor( protected platformUtilsService: PlatformUtilsService, protected environmentService: EnvironmentService, - protected i18nService: I18nService + protected i18nService: I18nService, + private modalService: ModalService ) { const urls = this.environmentService.getUrls(); @@ -59,5 +62,6 @@ export class EnvironmentComponent { protected saved() { this.onSaved.emit(); + this.modalService.closeAll(); } } diff --git a/libs/common/src/services/environment.service.ts b/libs/common/src/services/environment.service.ts index e093f0891a..2c6df478eb 100644 --- a/libs/common/src/services/environment.service.ts +++ b/libs/common/src/services/environment.service.ts @@ -218,6 +218,8 @@ export class EnvironmentService implements EnvironmentServiceAbstraction { return ![ "http://vault.bitwarden.com", "https://vault.bitwarden.com", + "http://vault.bitwarden.eu", + "https://vault.bitwarden.eu", "http://vault.qa.bitwarden.pw", "https://vault.qa.bitwarden.pw", ].includes(this.getWebVaultUrl()); From 27094057f82c0221236ad007a6eaa5c1080b2b79 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 11:17:15 +0200 Subject: [PATCH 24/75] chore(deps): update dependency tsconfig-paths-webpack-plugin to v4 (#5481) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 69 +++++++++++++++++++++++++++++++++++++++++++---- package.json | 2 +- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 168de48504..3d5b1b1357 100644 --- a/package-lock.json +++ b/package-lock.json @@ -167,7 +167,7 @@ "tailwindcss": "3.3.2", "ts-jest": "29.1.0", "ts-loader": "9.4.2", - "tsconfig-paths-webpack-plugin": "3.5.2", + "tsconfig-paths-webpack-plugin": "4.0.1", "type-fest": "2.19.0", "typescript": "4.9.5", "url": "0.11.0", @@ -7495,6 +7495,39 @@ "webpack": "*" } }, + "node_modules/@storybook/angular/node_modules/tsconfig-paths-webpack-plugin": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz", + "integrity": "sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^3.9.0" + } + }, + "node_modules/@storybook/angular/node_modules/tsconfig-paths-webpack-plugin/node_modules/enhanced-resolve": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz", + "integrity": "sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@storybook/angular/node_modules/tsconfig-paths-webpack-plugin/node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@storybook/api": { "version": "6.5.16", "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.5.16.tgz", @@ -42523,14 +42556,40 @@ } }, "node_modules/tsconfig-paths-webpack-plugin": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz", - "integrity": "sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.1.tgz", + "integrity": "sha512-m5//KzLoKmqu2MVix+dgLKq70MnFi8YL8sdzQZ6DblmCdfuq/y3OqvJd5vMndg2KEVCOeNz8Es4WVZhYInteLw==", "dev": true, "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^3.9.0" + "tsconfig-paths": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/tsconfig-paths/node_modules/json5": { diff --git a/package.json b/package.json index c8e69c64b3..0bdd5e95ff 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "tailwindcss": "3.3.2", "ts-jest": "29.1.0", "ts-loader": "9.4.2", - "tsconfig-paths-webpack-plugin": "3.5.2", + "tsconfig-paths-webpack-plugin": "4.0.1", "type-fest": "2.19.0", "typescript": "4.9.5", "url": "0.11.0", From 73e03bab8176976d23c21dcbe99358a2b30379ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 11:30:47 +0200 Subject: [PATCH 25/75] Autosync the updated translations (#5490) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/af/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ar/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/az/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/be/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/bg/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/bn/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/bs/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ca/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/cs/messages.json | 18 ++++++++++++++++-- apps/desktop/src/locales/cy/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/da/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/de/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/el/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/en_GB/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/en_IN/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/eo/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/es/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/et/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/eu/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/fa/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/fi/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/fil/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/fr/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/gl/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/he/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/hi/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/hr/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/hu/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/id/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/it/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ja/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ka/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/km/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/kn/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ko/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/lv/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/me/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ml/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/my/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/nb/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ne/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/nl/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/nn/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/or/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/pl/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/pt_BR/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/pt_PT/messages.json | 20 +++++++++++++++++--- apps/desktop/src/locales/ro/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/ru/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/si/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/sk/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/sl/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/sr/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/sv/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/te/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/th/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/tr/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/uk/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/vi/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/zh_CN/messages.json | 14 ++++++++++++++ apps/desktop/src/locales/zh_TW/messages.json | 14 ++++++++++++++ 61 files changed, 859 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index 3f1b4c73d4..f9843da28b 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index df54e50e2f..7e558adc15 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "تحديث الإعدادات الموصى بها" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index 0a4608e4fd..e409110b05 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Tövsiyə edilən Tənzimləmələr Güncəlləməsi" + }, + "region": { + "message": "Bölgə" + }, + "eu": { + "message": "AB", + "description": "European Union" + }, + "us": { + "message": "ABŞ", + "description": "United States" + }, + "selfHosted": { + "message": "Öz-özünə sahiblik edən" } } diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index cdabb7e793..efd52d6444 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Рэкамендаваныя налады абнаўлення" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index f0bac933df..4c89371192 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Препоръчителна промяна на настройките" + }, + "region": { + "message": "Регион" + }, + "eu": { + "message": "ЕС", + "description": "European Union" + }, + "us": { + "message": "САЩ", + "description": "United States" + }, + "selfHosted": { + "message": "Собствен хостинг" } } diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index 7d4cfb2eb3..f6972836d9 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 118b5be7ce..e5cc399e20 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index b2905fc5a0..e0d1adf7e5 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Actualització de configuració recomanada" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 391f2311ec..e35a5d78d2 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -1985,10 +1985,10 @@ "message": "Vypršel časový limit relace. Vraťte se zpět a zkuste se znovu přihlásit." }, "exportingPersonalVaultTitle": { - "message": "Exportování individuálního trezoru" + "message": "Exportování osobního trezoru" }, "exportingPersonalVaultDescription": { - "message": "Budou exportovány pouze jednotlivé položky trezoru spojené s $EMAIL$ . Nebudou zahrnuty položky trezoru v organizaci.", + "message": "Budou exportovány jen osobní položky trezoru spojené s účtem $EMAIL$. Nebudou zahrnuty položky trezoru v organizaci.", "placeholders": { "email": { "content": "$1", @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Aktualizace doporučených nastavení" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Vlastní hosting" } } diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index 13b91e222b..fbc7635f3b 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index 6ea996538e..6d915a97ab 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Anbefalet indstillingsopdatering" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "USA", + "description": "United States" + }, + "selfHosted": { + "message": "Selv-hostet" } } diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 9bde505fee..a757de46dc 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Empfohlene Aktualisierung der Einstellungen" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Selbst gehostet" } } diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index 69a2f127d7..bb84afe7d0 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index 8fa8ea82d0..fd9426f642 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index 4dc29b8f34..f3ee40a6dd 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 1139f03eea..bb86246b2d 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index a7ff6d0541..e8b8fa0b04 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Actualización de ajustes recomendados" + }, + "region": { + "message": "Región" + }, + "eu": { + "message": "Unión Europea", + "description": "European Union" + }, + "us": { + "message": "EE.UU.", + "description": "United States" + }, + "selfHosted": { + "message": "Autoalojado" } } diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index 9b1fdfa8a2..6f05a3f625 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index 3b3c2d7970..5e1323a74c 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index a2f2511297..220b53cda5 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "به‌روز رسانی تنظیمات توصیه شده" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 3269d10922..7287c306da 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Suositeltava asetusmuutos" + }, + "region": { + "message": "Alue" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Itse ylläpidetty" } } diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index 4afa545867..9613f221e9 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 83504d30ba..0fe9681d2d 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Une mise à jour des paramètres est recommandée" + }, + "region": { + "message": "Région" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Auto-hébergé" } } diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index 13b91e222b..fbc7635f3b 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index b4fcbf3a68..2cc3461e8a 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index b6c7c6e40d..2324d20019 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index adbf8764a6..dcf0ae8534 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 3fde5beaf8..4016a73db9 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Ajánlott beállítások frissítése" + }, + "region": { + "message": "Régió" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Saját kiszolgáló" } } diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index 1f163f4841..437838521a 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index 5d4cf2decb..90580d12aa 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Aggiornamento delle impostazioni consigliato" + }, + "region": { + "message": "Regione" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 5ea5481360..d1f1235067 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "設定の更新を推奨" + }, + "region": { + "message": "リージョン" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "米国", + "description": "United States" + }, + "selfHosted": { + "message": "自己ホスト型" } } diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 13b91e222b..fbc7635f3b 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index 13b91e222b..fbc7635f3b 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index 577dcda11e..2f1870a2b4 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index a97d51adeb..b5b4f69d78 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 550ee72fd9..705aa4ba5c 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Ieteicamie iestatījumu atjauninājumi" + }, + "region": { + "message": "Apgabals" + }, + "eu": { + "message": "ES", + "description": "European Union" + }, + "us": { + "message": "ASV", + "description": "United States" + }, + "selfHosted": { + "message": "Pašizvietots" } } diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index 6e0f3572f7..c6555d2e8d 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index 48b4aa9724..104d697f53 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index f3dca94dd9..545c17156b 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index dc62c1fe20..b431e2a14e 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index 13b91e222b..fbc7635f3b 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 66873ef00e..bcd3fd9441 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Aanbevolen instellingen" + }, + "region": { + "message": "Regio" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Zelfgehost" } } diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 48325eab3c..0b7b4ce113 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index b5750b7d07..ede0694974 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index 47959f42b3..2dd103dcd0 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Aktualizacja ustawień zalecanych" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Samodzielnie hostowany" } } diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index 57761b38c6..5e909f4735 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index d344572628..e7235d1ed9 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -570,7 +570,7 @@ "message": "Não existem itens para listar." }, "sendVerificationCode": { - "message": "Envie um código de verificação para o seu e-mail" + "message": "Enviar um código de verificação para o seu e-mail" }, "sendCode": { "message": "Enviar o código" @@ -1684,7 +1684,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "myVault": { - "message": "O meu Cofre" + "message": "O meu cofre" }, "text": { "message": "Texto" @@ -2052,7 +2052,7 @@ "message": "Procurar Organização" }, "searchMyVault": { - "message": "Procurar no meu Cofre" + "message": "Procurar no meu cofre" }, "forwardedEmail": { "message": "Forwarded email alias" @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Região" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "EUA", + "description": "United States" + }, + "selfHosted": { + "message": "Auto-hospedado" } } diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index df5d3af904..c5fc551e18 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index ea290c84c9..e940c97686 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Рекомендуемое обновление настроек" + }, + "region": { + "message": "Регион" + }, + "eu": { + "message": "Европа", + "description": "European Union" + }, + "us": { + "message": "США", + "description": "United States" + }, + "selfHosted": { + "message": "Собственный хостинг" } } diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index 7e05312723..e8a79147aa 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index ffafe222cc..773be1cd07 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Odporúčaná aktualizácia nastavenia" + }, + "region": { + "message": "Región" + }, + "eu": { + "message": "EÚ", + "description": "European Union" + }, + "us": { + "message": "USA", + "description": "United States" + }, + "selfHosted": { + "message": "Vlastný hosting" } } diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 6ad123c585..f670e572bc 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 894c3ea59e..fb225b1763 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Препоручено ажурирање поставки" + }, + "region": { + "message": "Регион" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Личан хостинг" } } diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index d1e242eb6a..247f646408 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index 13b91e222b..fbc7635f3b 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index fd5b9d7b92..e68d7d13c1 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index d7b4924010..294ab336c3 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Önerilen Ayarlar Güncellemesi" + }, + "region": { + "message": "Bölge" + }, + "eu": { + "message": "AB", + "description": "European Union" + }, + "us": { + "message": "ABD", + "description": "United States" + }, + "selfHosted": { + "message": "Barındırılan" } } diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index d86332f506..4e4c214ed9 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Оновлення рекомендованих налаштувань" + }, + "region": { + "message": "Регіон" + }, + "eu": { + "message": "ЄС", + "description": "European Union" + }, + "us": { + "message": "США", + "description": "United States" + }, + "selfHosted": { + "message": "Власне розміщення" } } diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index 8a810b8d84..e4fcbede49 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index d4a028271c..8184e19b76 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "推荐的设置更新" + }, + "region": { + "message": "区域" + }, + "eu": { + "message": "欧盟", + "description": "European Union" + }, + "us": { + "message": "美国", + "description": "United States" + }, + "selfHosted": { + "message": "自托管" } } diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index e248870ab3..a5df7cdde5 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -2251,5 +2251,19 @@ }, "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, + "selfHosted": { + "message": "Self-hosted" } } From 14084dcf59ff92a6e5a31d240dbf0021b5946e89 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 11:37:21 +0200 Subject: [PATCH 26/75] Autosync the updated translations (#5489) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 11 +++++++++++ apps/browser/src/_locales/az/messages.json | 11 +++++++++++ apps/browser/src/_locales/be/messages.json | 11 +++++++++++ apps/browser/src/_locales/bg/messages.json | 11 +++++++++++ apps/browser/src/_locales/bn/messages.json | 11 +++++++++++ apps/browser/src/_locales/bs/messages.json | 11 +++++++++++ apps/browser/src/_locales/ca/messages.json | 11 +++++++++++ apps/browser/src/_locales/cs/messages.json | 15 +++++++++++++-- apps/browser/src/_locales/cy/messages.json | 11 +++++++++++ apps/browser/src/_locales/da/messages.json | 11 +++++++++++ apps/browser/src/_locales/de/messages.json | 11 +++++++++++ apps/browser/src/_locales/el/messages.json | 11 +++++++++++ apps/browser/src/_locales/en_GB/messages.json | 8 ++++++++ apps/browser/src/_locales/en_IN/messages.json | 11 +++++++++++ apps/browser/src/_locales/es/messages.json | 11 +++++++++++ apps/browser/src/_locales/et/messages.json | 11 +++++++++++ apps/browser/src/_locales/eu/messages.json | 11 +++++++++++ apps/browser/src/_locales/fa/messages.json | 11 +++++++++++ apps/browser/src/_locales/fi/messages.json | 11 +++++++++++ apps/browser/src/_locales/fil/messages.json | 11 +++++++++++ apps/browser/src/_locales/fr/messages.json | 11 +++++++++++ apps/browser/src/_locales/gl/messages.json | 11 +++++++++++ apps/browser/src/_locales/he/messages.json | 11 +++++++++++ apps/browser/src/_locales/hi/messages.json | 11 +++++++++++ apps/browser/src/_locales/hr/messages.json | 11 +++++++++++ apps/browser/src/_locales/hu/messages.json | 11 +++++++++++ apps/browser/src/_locales/id/messages.json | 11 +++++++++++ apps/browser/src/_locales/it/messages.json | 11 +++++++++++ apps/browser/src/_locales/ja/messages.json | 11 +++++++++++ apps/browser/src/_locales/ka/messages.json | 11 +++++++++++ apps/browser/src/_locales/km/messages.json | 11 +++++++++++ apps/browser/src/_locales/kn/messages.json | 11 +++++++++++ apps/browser/src/_locales/ko/messages.json | 11 +++++++++++ apps/browser/src/_locales/lt/messages.json | 11 +++++++++++ apps/browser/src/_locales/lv/messages.json | 11 +++++++++++ apps/browser/src/_locales/ml/messages.json | 11 +++++++++++ apps/browser/src/_locales/my/messages.json | 11 +++++++++++ apps/browser/src/_locales/nb/messages.json | 11 +++++++++++ apps/browser/src/_locales/ne/messages.json | 11 +++++++++++ apps/browser/src/_locales/nl/messages.json | 11 +++++++++++ apps/browser/src/_locales/nn/messages.json | 11 +++++++++++ apps/browser/src/_locales/or/messages.json | 11 +++++++++++ apps/browser/src/_locales/pl/messages.json | 11 +++++++++++ apps/browser/src/_locales/pt_BR/messages.json | 11 +++++++++++ apps/browser/src/_locales/pt_PT/messages.json | 17 ++++++++++++++--- apps/browser/src/_locales/ro/messages.json | 11 +++++++++++ apps/browser/src/_locales/ru/messages.json | 11 +++++++++++ apps/browser/src/_locales/si/messages.json | 11 +++++++++++ apps/browser/src/_locales/sk/messages.json | 11 +++++++++++ apps/browser/src/_locales/sl/messages.json | 13 ++++++++++++- apps/browser/src/_locales/sr/messages.json | 11 +++++++++++ apps/browser/src/_locales/sv/messages.json | 11 +++++++++++ apps/browser/src/_locales/te/messages.json | 11 +++++++++++ apps/browser/src/_locales/th/messages.json | 11 +++++++++++ apps/browser/src/_locales/tr/messages.json | 11 +++++++++++ apps/browser/src/_locales/uk/messages.json | 11 +++++++++++ apps/browser/src/_locales/vi/messages.json | 11 +++++++++++ apps/browser/src/_locales/zh_CN/messages.json | 11 +++++++++++ apps/browser/src/_locales/zh_TW/messages.json | 11 +++++++++++ 59 files changed, 652 insertions(+), 6 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 609f6ef39d..71cd3d1a66 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 9ad7b097ab..0c12f845d5 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Bölgə" + }, "opensInANewWindow": { "message": "Yeni bir pəncərədə açılır" + }, + "eu": { + "message": "AB", + "description": "European Union" + }, + "us": { + "message": "ABŞ", + "description": "United States" } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 4d0fe3698d..80800f4aa3 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Адкрываць у новым акне" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index bc3feb2469..b17692bc83 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Регион" + }, "opensInANewWindow": { "message": "Отваря се в нов прозорец" + }, + "eu": { + "message": "ЕС", + "description": "European Union" + }, + "us": { + "message": "САЩ", + "description": "United States" } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 9ddc1b03ec..76143e7619 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index 3f37ef10f7..b3047a9878 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 1028885f50..e117d21790 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "S'obri en una finestra nova" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index 7ff5424a05..d83282e08a 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -1977,10 +1977,10 @@ "message": "Vypršel časový limit relace. Vraťte se zpět a zkuste se znovu přihlásit." }, "exportingPersonalVaultTitle": { - "message": "Exportování individuálního trezoru" + "message": "Exportování osobního trezoru" }, "exportingPersonalVaultDescription": { - "message": "Budou exportovány pouze položky trezoru spojené s účtem $EMAIL$. Nebudou zahrnuty položky trezoru v organizaci.", + "message": "Budou exportovány jen osobní položky trezoru spojené s účtem $EMAIL$. Nebudou zahrnuty položky trezoru v organizaci.", "placeholders": { "email": { "content": "$1", @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Otevře se v novém okně" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 53451d098e..5aebf5dd80 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Åbnes i et nyt vindue" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "USA", + "description": "United States" } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index c6f7b90988..c7827d4ddc 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Wird in einem neuen Fenster geöffnet" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index d86d1be57e..e6da9f04c8 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Ανοίγει σε νέο παράθυρο" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 3b54fe0efe..653ff32074 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -2226,5 +2226,13 @@ }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index de8b595765..3fe6222cfc 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index ac4b28b7dd..afd3ea4ce8 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Región" + }, "opensInANewWindow": { "message": "Abre en una nueva ventana" + }, + "eu": { + "message": "Unión Europea", + "description": "European Union" + }, + "us": { + "message": "EE.UU.", + "description": "United States" } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 8ccfcb5dcc..02ee8d0438 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Piirkond" + }, "opensInANewWindow": { "message": "Avaneb uues aknas" + }, + "eu": { + "message": "EL", + "description": "European Union" + }, + "us": { + "message": "USA", + "description": "United States" } } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 9d2196ed64..e2189ce6a6 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 6a13d95927..0e4a59e164 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "در پنجره جدید باز می‌شود" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 4edb1b563c..69b77b2612 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Alue" + }, "opensInANewWindow": { "message": "Avautuu uudessa ikkunassa" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index af8050b68a..e98884c200 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index ae4893dd81..8f4e769c69 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Région" + }, "opensInANewWindow": { "message": "S'ouvre dans une nouvelle fenêtre" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index e4e676471f..fc90bade6c 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 456822a3cc..df561ad0e4 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index d668e3e0d2..37ecb3de8c 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index d06a236f69..c5e8214b63 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Régió" + }, "opensInANewWindow": { "message": "Megnyitás új ablakban" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 220af16b5a..6addc264fb 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index c3aab71545..1971331fd9 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Regione" + }, "opensInANewWindow": { "message": "Si apre in una nuova finestra" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index e6eca2c538..630dfb3e21 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "リージョン" + }, "opensInANewWindow": { "message": "新しいウィンドウで開く" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "米国", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index d71e9402df..2f484324f3 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index 31b78ceb49..baa61fad17 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 155736462d..962fe7347c 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 078c28a261..e6a9dbdc5c 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 317a1d48cc..38c892aaed 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Apgabals" + }, "opensInANewWindow": { "message": "Atver jaunā logā" + }, + "eu": { + "message": "ES", + "description": "European Union" + }, + "us": { + "message": "ASV", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 1975bb0f14..4c4e9936e0 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 0946027aee..8ede2fb938 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 1f76bc82fe..cf3cae05d4 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Regio" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 36f8cc8c94..ca32eb73aa 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Otwiera w nowym oknie" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 8b4fcfad0a..87585d561d 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index ad53f10e41..9950328204 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -56,7 +56,7 @@ "message": "Cofre" }, "myVault": { - "message": "O meu Cofre" + "message": "O meu cofre" }, "allVaults": { "message": "Todos os Cofres" @@ -128,7 +128,7 @@ "message": "Continuar" }, "sendVerificationCode": { - "message": "Envie um código de verificação para o seu e-mail" + "message": "Enviar um código de verificação para o seu e-mail" }, "sendCode": { "message": "Enviar o código" @@ -1744,7 +1744,7 @@ } }, "custom": { - "message": "Custom" + "message": "Personalizado" }, "maximumAccessCount": { "message": "Maximum Access Count" @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Região" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "EUA", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index bad505607a..47a684aa1a 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 1b15850d27..9da7f861dc 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Регион" + }, "opensInANewWindow": { "message": "Откроется в новом окне" + }, + "eu": { + "message": "Европа", + "description": "European Union" + }, + "us": { + "message": "США", + "description": "United States" } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 9b917a74db..94baba9b6d 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 147fe0bbd4..2fa04daf3d 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Región" + }, "opensInANewWindow": { "message": "Otvárať v novom okne" + }, + "eu": { + "message": "EÚ", + "description": "European Union" + }, + "us": { + "message": "USA", + "description": "United States" } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 32f3f860fa..91fdc621fd 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -2180,7 +2180,7 @@ "message": "Kako uporabljati samodejno izpolnjevanje" }, "autofillSelectInfoWithCommand": { - "message": "Izberite element na tej strani ali pa uporabite bližnjico $COMMAND$", + "message": "Izberite element na tej strani ali pa uporabite bližnjico $COMMAND$.", "placeholders": { "command": { "content": "$1", @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Odpre se v novem oknu" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index a0368285da..952ae90145 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Регион" + }, "opensInANewWindow": { "message": "Отвара се у новом прозору" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index a270aedb9b..79afc8729d 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Öppnas i ett nytt fönster" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 0a69b94887..69d26333a8 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 6a355591f6..1e43987ab0 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 4f904da244..cdc8e109fe 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Bölge" + }, "opensInANewWindow": { "message": "Yeni pencerede açılır" + }, + "eu": { + "message": "AB", + "description": "European Union" + }, + "us": { + "message": "ABD", + "description": "United States" } } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 336bf3d39a..1969bc3362 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Регіон" + }, "opensInANewWindow": { "message": "Відкривається у новому вікні" + }, + "eu": { + "message": "ЄС", + "description": "European Union" + }, + "us": { + "message": "США", + "description": "United States" } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index f7aea9e151..fee4c66f3a 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 0f7d9870e1..45c3c62db0 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "区域" + }, "opensInANewWindow": { "message": "在新窗口中打开" + }, + "eu": { + "message": "欧盟", + "description": "European Union" + }, + "us": { + "message": "美国", + "description": "United States" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 83bd8bd8e3..42e082f136 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -2221,7 +2221,18 @@ } } }, + "region": { + "message": "Region" + }, "opensInANewWindow": { "message": "Opens in a new window" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" } } From b31203d64fbdbc0eaef41a94b00bc85cfe998a18 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 22 May 2023 17:28:00 +0200 Subject: [PATCH 27/75] Added textarea (#4155) --- apps/browser/src/autofill/content/autofill.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/browser/src/autofill/content/autofill.js b/apps/browser/src/autofill/content/autofill.js index 661eb8e252..052fd1120f 100644 --- a/apps/browser/src/autofill/content/autofill.js +++ b/apps/browser/src/autofill/content/autofill.js @@ -676,7 +676,7 @@ var els = []; try { var elsList = theDoc.querySelectorAll('input:not([type="hidden"]):not([type="submit"]):not([type="reset"])' + - ':not([type="button"]):not([type="image"]):not([type="file"]):not([data-bwignore]), select, ' + + ':not([type="button"]):not([type="image"]):not([type="file"]):not([data-bwignore]), select, textarea, ' + 'span[data-bwautofill]'); els = Array.prototype.slice.call(elsList); } catch (e) { } @@ -1177,7 +1177,7 @@ } try { // START MODIFICATION - var elements = Array.prototype.slice.call(selectAllFromDoc('input, select, button, ' + + var elements = Array.prototype.slice.call(selectAllFromDoc('input, select, button, textarea, ' + 'span[data-bwautofill]')); // END MODIFICATION var filteredElements = elements.filter(function (o) { From 62591a8bc8d7dcf754db92d742cb3bfe70b9fbc6 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Mon, 22 May 2023 20:19:16 +0200 Subject: [PATCH 28/75] [PM-2328] Fix jest deprecations (#5483) --- apps/browser/jest.config.js | 3 ++- apps/cli/jest.config.js | 6 +++-- apps/desktop/jest.config.js | 3 ++- apps/web/jest.config.js | 4 +-- bitwarden_license/bit-web/jest.config.js | 4 +-- jest.config.js | 11 ++------ libs/angular/jest.config.js | 3 ++- libs/common/jest.config.js | 3 ++- libs/components/jest.config.js | 3 ++- libs/exporter/jest.config.js | 3 ++- libs/importer/jest.config.js | 3 ++- libs/node/jest.config.js | 3 ++- libs/shared/jest.config.angular.js | 32 ++++++++++++++++++++++++ libs/shared/jest.config.base.js | 27 -------------------- libs/shared/jest.config.ts.js | 29 +++++++++++++++++++++ 15 files changed, 87 insertions(+), 50 deletions(-) create mode 100644 libs/shared/jest.config.angular.js delete mode 100644 libs/shared/jest.config.base.js create mode 100644 libs/shared/jest.config.ts.js diff --git a/apps/browser/jest.config.js b/apps/browser/jest.config.js index 4f954afa9e..cde02cd995 100644 --- a/apps/browser/jest.config.js +++ b/apps/browser/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("./tsconfig"); -const sharedConfig = require("../../libs/shared/jest.config.base"); +const sharedConfig = require("../../libs/shared/jest.config.angular"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "jest-preset-angular", diff --git a/apps/cli/jest.config.js b/apps/cli/jest.config.js index 67116d394b..8765ccc8e4 100644 --- a/apps/cli/jest.config.js +++ b/apps/cli/jest.config.js @@ -1,8 +1,10 @@ const { pathsToModuleNameMapper } = require("ts-jest"); -const { compilerOptions } = require("./tsconfig.json"); -const sharedConfig = require("../../libs/shared/jest.config.base"); +const { compilerOptions } = require("./tsconfig"); +const sharedConfig = require("../../libs/shared/jest.config.ts"); + +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "ts-jest", diff --git a/apps/desktop/jest.config.js b/apps/desktop/jest.config.js index 4f954afa9e..cde02cd995 100644 --- a/apps/desktop/jest.config.js +++ b/apps/desktop/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("./tsconfig"); -const sharedConfig = require("../../libs/shared/jest.config.base"); +const sharedConfig = require("../../libs/shared/jest.config.angular"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "jest-preset-angular", diff --git a/apps/web/jest.config.js b/apps/web/jest.config.js index 707e8960e3..cde02cd995 100644 --- a/apps/web/jest.config.js +++ b/apps/web/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("./tsconfig"); -const sharedConfig = require("../../libs/shared/jest.config.base"); +const sharedConfig = require("../../libs/shared/jest.config.angular"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "jest-preset-angular", @@ -11,5 +12,4 @@ module.exports = { moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { prefix: "/", }), - modulePathIgnorePatterns: ["jslib"], }; diff --git a/bitwarden_license/bit-web/jest.config.js b/bitwarden_license/bit-web/jest.config.js index 84c6866a7d..17b7139049 100644 --- a/bitwarden_license/bit-web/jest.config.js +++ b/bitwarden_license/bit-web/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("./tsconfig"); -const sharedConfig = require("../../libs/shared/jest.config.base"); +const sharedConfig = require("../../libs/shared/jest.config.angular"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "jest-preset-angular", @@ -11,5 +12,4 @@ module.exports = { moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { prefix: "/", }), - modulePathIgnorePatterns: ["jslib"], }; diff --git a/jest.config.js b/jest.config.js index ec58fe0c01..8b54a82658 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,12 +2,14 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("./tsconfig"); +/** @type {import('jest').Config} */ module.exports = { reporters: ["default", "jest-junit"], collectCoverage: true, coverageReporters: ["html", "lcov"], coverageDirectory: "coverage", + moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { prefix: "/", }), @@ -30,13 +32,4 @@ module.exports = { // https://github.com/facebook/jest/issues/9430#issuecomment-1149882002 // Also anecdotally improves performance when run locally maxWorkers: 3, - globals: { - "ts-jest": { - // Further workaround for memory leak, recommended here: - // https://github.com/kulshekhar/ts-jest/issues/1967#issuecomment-697494014 - // Makes tests run faster and reduces size/rate of leak, but loses typechecking on test code - // See https://bitwarden.atlassian.net/browse/EC-497 for more info - isolatedModules: true, - }, - }, }; diff --git a/libs/angular/jest.config.js b/libs/angular/jest.config.js index 3be0f66db5..e294e4ff47 100644 --- a/libs/angular/jest.config.js +++ b/libs/angular/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("../shared/tsconfig.libs"); -const sharedConfig = require("../../libs/shared/jest.config.base"); +const sharedConfig = require("../../libs/shared/jest.config.angular"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, displayName: "libs/angular tests", diff --git a/libs/common/jest.config.js b/libs/common/jest.config.js index 29309a7830..d7f78abbf3 100644 --- a/libs/common/jest.config.js +++ b/libs/common/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("../shared/tsconfig.libs"); -const sharedConfig = require("../shared/jest.config.base"); +const sharedConfig = require("../shared/jest.config.ts"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, displayName: "libs/common tests", diff --git a/libs/components/jest.config.js b/libs/components/jest.config.js index e90c663ce9..2f4b1ed15d 100644 --- a/libs/components/jest.config.js +++ b/libs/components/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("./tsconfig"); -const sharedConfig = require("../../libs/shared/jest.config.base"); +const sharedConfig = require("../../libs/shared/jest.config.angular"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, displayName: "libs/components tests", diff --git a/libs/exporter/jest.config.js b/libs/exporter/jest.config.js index 2eeeefad62..68daba3d40 100644 --- a/libs/exporter/jest.config.js +++ b/libs/exporter/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("../shared/tsconfig.libs"); -const sharedConfig = require("../shared/jest.config.base"); +const sharedConfig = require("../shared/jest.config.ts"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "ts-jest", diff --git a/libs/importer/jest.config.js b/libs/importer/jest.config.js index 2eeeefad62..68daba3d40 100644 --- a/libs/importer/jest.config.js +++ b/libs/importer/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("../shared/tsconfig.libs"); -const sharedConfig = require("../shared/jest.config.base"); +const sharedConfig = require("../shared/jest.config.ts"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "ts-jest", diff --git a/libs/node/jest.config.js b/libs/node/jest.config.js index 833d03cfa5..fd7d580fda 100644 --- a/libs/node/jest.config.js +++ b/libs/node/jest.config.js @@ -2,8 +2,9 @@ const { pathsToModuleNameMapper } = require("ts-jest"); const { compilerOptions } = require("../shared/tsconfig.libs"); -const sharedConfig = require("../shared/jest.config.base"); +const sharedConfig = require("../shared/jest.config.ts"); +/** @type {import('jest').Config} */ module.exports = { ...sharedConfig, preset: "ts-jest", diff --git a/libs/shared/jest.config.angular.js b/libs/shared/jest.config.angular.js new file mode 100644 index 0000000000..a0dcc27516 --- /dev/null +++ b/libs/shared/jest.config.angular.js @@ -0,0 +1,32 @@ +/* eslint-env node */ +/* eslint-disable @typescript-eslint/no-var-requires */ +const { defaultTransformerOptions } = require("jest-preset-angular/presets"); + +/** @type {import('jest').Config} */ +module.exports = { + testMatch: ["**/+(*.)+(spec).+(ts)"], + + // Workaround for a memory leak that crashes tests in CI: + // https://github.com/facebook/jest/issues/9430#issuecomment-1149882002 + // Also anecdotally improves performance when run locally + maxWorkers: 3, + + transform: { + "^.+\\.(ts|js|mjs|svg)$": [ + "jest-preset-angular", + { + ...defaultTransformerOptions, + // Jest does not use tsconfig.spec.json by default + tsconfig: "/tsconfig.spec.json", + // Further workaround for memory leak, recommended here: + // https://github.com/kulshekhar/ts-jest/issues/1967#issuecomment-697494014 + // Makes tests run faster and reduces size/rate of leak, but loses typechecking on test code + // See https://bitwarden.atlassian.net/browse/EC-497 for more info + isolatedModules: true, + astTransformers: { + before: ["/../../libs/shared/es2020-transformer.ts"], + }, + }, + ], + }, +}; diff --git a/libs/shared/jest.config.base.js b/libs/shared/jest.config.base.js deleted file mode 100644 index e0eda1c4ca..0000000000 --- a/libs/shared/jest.config.base.js +++ /dev/null @@ -1,27 +0,0 @@ -/* eslint-env node */ -module.exports = { - testMatch: ["**/+(*.)+(spec).+(ts)"], - collectCoverage: true, - coverageReporters: ["html", "lcov"], - coverageDirectory: "coverage", - - // Workaround for a memory leak that crashes tests in CI: - // https://github.com/facebook/jest/issues/9430#issuecomment-1149882002 - // Also anecdotally improves performance when run locally - maxWorkers: 3, - - globals: { - "ts-jest": { - // Jest does not use tsconfig.spec.json by default - tsconfig: "/tsconfig.spec.json", - // Further workaround for memory leak, recommended here: - // https://github.com/kulshekhar/ts-jest/issues/1967#issuecomment-697494014 - // Makes tests run faster and reduces size/rate of leak, but loses typechecking on test code - // See https://bitwarden.atlassian.net/browse/EC-497 for more info - isolatedModules: true, - astTransformers: { - before: ["/../../libs/shared/es2020-transformer.ts"], - }, - }, - }, -}; diff --git a/libs/shared/jest.config.ts.js b/libs/shared/jest.config.ts.js new file mode 100644 index 0000000000..04ab80859b --- /dev/null +++ b/libs/shared/jest.config.ts.js @@ -0,0 +1,29 @@ +/* eslint-env node */ + +/** @type {import('jest').Config} */ +module.exports = { + testMatch: ["**/+(*.)+(spec).+(ts)"], + + // Workaround for a memory leak that crashes tests in CI: + // https://github.com/facebook/jest/issues/9430#issuecomment-1149882002 + // Also anecdotally improves performance when run locally + maxWorkers: 3, + + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + // Jest does not use tsconfig.spec.json by default + tsconfig: "/tsconfig.spec.json", + // Further workaround for memory leak, recommended here: + // https://github.com/kulshekhar/ts-jest/issues/1967#issuecomment-697494014 + // Makes tests run faster and reduces size/rate of leak, but loses typechecking on test code + // See https://bitwarden.atlassian.net/browse/EC-497 for more info + isolatedModules: true, + astTransformers: { + before: ["/../../libs/shared/es2020-transformer.ts"], + }, + }, + ], + }, +}; From 3a1ae46c37496b87ba6cd64a8150e11cb342f2ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 13:13:42 -0600 Subject: [PATCH 29/75] chore(deps): update crowdin/github-action action to v1.8.1 (#5484) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-browser.yml | 2 +- .github/workflows/build-desktop.yml | 2 +- .github/workflows/build-web.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index 468e8b3b54..7270cc9203 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -360,7 +360,7 @@ jobs: secrets: "crowdin-api-token" - name: Upload Sources - uses: crowdin/github-action@3cabba4ddfd0579a1236b3fb68405236dc489ccc # v1.8.0 + uses: crowdin/github-action@102b5aa21783a64027193ef802a616140a1ca102 # v1.8.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 6c614df483..7935e2a8ec 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -1196,7 +1196,7 @@ jobs: secrets: "crowdin-api-token" - name: Upload Sources - uses: crowdin/github-action@3cabba4ddfd0579a1236b3fb68405236dc489ccc # v1.8.0 + uses: crowdin/github-action@102b5aa21783a64027193ef802a616140a1ca102 # v1.8.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 8fed2825a9..9151650a7b 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -297,7 +297,7 @@ jobs: secrets: "crowdin-api-token" - name: Upload Sources - uses: crowdin/github-action@3cabba4ddfd0579a1236b3fb68405236dc489ccc # v1.8.0 + uses: crowdin/github-action@102b5aa21783a64027193ef802a616140a1ca102 # v1.8.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} From 946d254b0fa159dfa4926796340f7a2dd2ac5db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bispo?= Date: Mon, 22 May 2023 23:04:50 +0100 Subject: [PATCH 30/75] [PM-2347] Fix EU env flag (#5495) --- .../src/auth/components/environment-selector.component.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/angular/src/auth/components/environment-selector.component.html b/libs/angular/src/auth/components/environment-selector.component.html index 53c177ee1d..e64d09da06 100644 --- a/libs/angular/src/auth/components/environment-selector.component.html +++ b/libs/angular/src/auth/components/environment-selector.component.html @@ -48,6 +48,7 @@ type="button" class="environment-selector-dialog-item" (click)="toggle(ServerEnvironmentType.EU)" + *ngIf="euServerFlagEnabled" > {{ "eu" | i18n }} -
+
- diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.ts b/apps/web/src/app/admin-console/organizations/settings/account.component.ts index 0072e1f3ae..473ce88f2d 100644 --- a/apps/web/src/app/admin-console/organizations/settings/account.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/account.component.ts @@ -1,6 +1,8 @@ import { Component, ViewChild, ViewContainerRef } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; +import { lastValueFrom } from "rxjs"; +import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ModalService } from "@bitwarden/angular/services/modal.service"; import { CryptoService } from "@bitwarden/common/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -15,7 +17,7 @@ import { OrganizationResponse } from "@bitwarden/common/admin-console/models/res import { ApiKeyComponent } from "../../../settings/api-key.component"; import { PurgeVaultComponent } from "../../../settings/purge-vault.component"; -import { DeleteOrganizationComponent } from "./delete-organization.component"; +import { DeleteOrganizationDialogResult, openDeleteOrganizationDialog } from "./components"; @Component({ selector: "app-org-account", @@ -23,8 +25,6 @@ import { DeleteOrganizationComponent } from "./delete-organization.component"; }) // eslint-disable-next-line rxjs-angular/prefer-takeuntil export class AccountComponent { - @ViewChild("deleteOrganizationTemplate", { read: ViewContainerRef, static: true }) - deleteModalRef: ViewContainerRef; @ViewChild("purgeOrganizationTemplate", { read: ViewContainerRef, static: true }) purgeModalRef: ViewContainerRef; @ViewChild("apiKeyTemplate", { read: ViewContainerRef, static: true }) @@ -51,7 +51,8 @@ export class AccountComponent { private logService: LogService, private router: Router, private organizationService: OrganizationService, - private organizationApiService: OrganizationApiServiceAbstraction + private organizationApiService: OrganizationApiServiceAbstraction, + private dialogService: DialogServiceAbstraction ) {} async ngOnInit() { @@ -100,17 +101,18 @@ export class AccountComponent { } async deleteOrganization() { - await this.modalService.openViewRef( - DeleteOrganizationComponent, - this.deleteModalRef, - (comp) => { - comp.organizationId = this.organizationId; - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - comp.onSuccess.subscribe(() => { - this.router.navigate(["/"]); - }); - } - ); + const dialog = openDeleteOrganizationDialog(this.dialogService, { + data: { + organizationId: this.organizationId, + requestType: "RegularDelete", + }, + }); + + const result = await lastValueFrom(dialog.closed); + + if (result === DeleteOrganizationDialogResult.Deleted) { + this.router.navigate(["/"]); + } } async purgeVault() { diff --git a/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.html b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.html new file mode 100644 index 0000000000..f963d27b8d --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.html @@ -0,0 +1,40 @@ + + + {{ "deleteOrganization" | i18n }} +
+ {{ + "deletingOrganizationIsPermanentWarning" | i18n : organization?.name + }} +

+ + {{ "orgCreatedSponsorshipInvalid" | i18n }} + + + + {{ "deletingOrganizationContentWarning" | i18n : organization?.name }} +

    +
  • + {{ type.count }} {{ type.localizationKey | i18n }} +
  • +
+ {{ "deletingOrganizationActiveUserAccountsWarning" | i18n }} + + +

+ +
+
+ + +
+
+ diff --git a/apps/web/src/app/admin-console/organizations/settings/delete-organization.component.ts b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts similarity index 57% rename from apps/web/src/app/admin-console/organizations/settings/delete-organization.component.ts rename to apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts index cec096955a..e99a0d2910 100644 --- a/apps/web/src/app/admin-console/organizations/settings/delete-organization.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts @@ -1,17 +1,25 @@ -import { Component, EventEmitter, OnInit, Output } from "@angular/core"; +import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; +import { Component, Inject, OnDestroy, OnInit } from "@angular/core"; +import { FormBuilder, FormControl, Validators } from "@angular/forms"; +import { combineLatest, Subject, takeUntil } from "rxjs"; +import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Utils } from "@bitwarden/common/misc/utils"; import { Verification } from "@bitwarden/common/types/verification"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { UserVerificationModule } from "../../../../shared/components/user-verification"; +import { SharedModule } from "../../../../shared/shared.module"; + class CountBasedLocalizationKey { singular: string; plural: string; @@ -43,63 +51,90 @@ class OrganizationContentSummary { itemCountByType: OrganizationContentSummaryItem[] = []; } +export interface DeleteOrganizationDialogParams { + organizationId: string; + + requestType: "InvalidFamiliesForEnterprise" | "RegularDelete"; +} + +export enum DeleteOrganizationDialogResult { + Deleted = "deleted", + Canceled = "canceled", +} + @Component({ selector: "app-delete-organization", - templateUrl: "delete-organization.component.html", + standalone: true, + imports: [SharedModule, UserVerificationModule], + templateUrl: "delete-organization-dialog.component.html", }) -export class DeleteOrganizationComponent implements OnInit { - organizationId: string; +export class DeleteOrganizationDialogComponent implements OnInit, OnDestroy { + private destroy$ = new Subject(); + loaded: boolean; deleteOrganizationRequestType: "InvalidFamiliesForEnterprise" | "RegularDelete" = "RegularDelete"; - organizationName: string; + organization: Organization; organizationContentSummary: OrganizationContentSummary = new OrganizationContentSummary(); - @Output() onSuccess: EventEmitter = new EventEmitter(); + secret: Verification; - masterPassword: Verification; + protected formGroup = this.formBuilder.group({ + secret: new FormControl(null, [Validators.required]), + }); formPromise: Promise; constructor( + @Inject(DIALOG_DATA) private params: DeleteOrganizationDialogParams, + private dialogRef: DialogRef, private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private userVerificationService: UserVerificationService, private logService: LogService, private cipherService: CipherService, private organizationService: OrganizationService, - private organizationApiService: OrganizationApiServiceAbstraction + private organizationApiService: OrganizationApiServiceAbstraction, + private formBuilder: FormBuilder ) {} - async ngOnInit(): Promise { - await this.load(); + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); } - async submit() { + async ngOnInit(): Promise { + this.deleteOrganizationRequestType = this.params.requestType; + + combineLatest([ + this.organizationService.get$(this.params.organizationId), + this.cipherService.getAllFromApiForOrganization(this.params.organizationId), + ]) + .pipe(takeUntil(this.destroy$)) + .subscribe(([organization, ciphers]) => { + this.organization = organization; + this.organizationContentSummary = this.buildOrganizationContentSummary(ciphers); + this.loaded = true; + }); + } + + protected submit = async () => { try { this.formPromise = this.userVerificationService - .buildRequest(this.masterPassword) - .then((request) => this.organizationApiService.delete(this.organizationId, request)); + .buildRequest(this.formGroup.value.secret) + .then((request) => this.organizationApiService.delete(this.organization.id, request)); await this.formPromise; this.platformUtilsService.showToast( "success", this.i18nService.t("organizationDeleted"), this.i18nService.t("organizationDeletedDesc") ); - this.onSuccess.emit(); + this.dialogRef.close(DeleteOrganizationDialogResult.Deleted); } catch (e) { this.logService.error(e); } - } + }; - private async load() { - this.organizationName = (await this.organizationService.get(this.organizationId)).name; - this.organizationContentSummary = await this.buildOrganizationContentSummary(); - this.loaded = true; - } - - private async buildOrganizationContentSummary(): Promise { + private buildOrganizationContentSummary(ciphers: CipherView[]): OrganizationContentSummary { const organizationContentSummary = new OrganizationContentSummary(); - const organizationItems = ( - await this.cipherService.getAllFromApiForOrganization(this.organizationId) - ).filter((item) => item.deletedDate == null); + const organizationItems = ciphers.filter((item) => item.deletedDate == null); if (organizationItems.length < 1) { return organizationContentSummary; @@ -129,3 +164,18 @@ export class DeleteOrganizationComponent implements OnInit { return new CountBasedLocalizationKey(`type${type}`, `type${type}Plural`); } } + +/** + * Strongly typed helper to open a Delete Organization dialog + * @param dialogService Instance of the dialog service that will be used to open the dialog + * @param config Configuration for the dialog + */ +export function openDeleteOrganizationDialog( + dialogService: DialogServiceAbstraction, + config: DialogConfig +) { + return dialogService.open( + DeleteOrganizationDialogComponent, + config + ); +} diff --git a/apps/web/src/app/admin-console/organizations/settings/components/index.ts b/apps/web/src/app/admin-console/organizations/settings/components/index.ts new file mode 100644 index 0000000000..ae4b74837d --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/settings/components/index.ts @@ -0,0 +1 @@ +export * from "./delete-organization-dialog.component"; diff --git a/apps/web/src/app/admin-console/organizations/settings/delete-organization.component.html b/apps/web/src/app/admin-console/organizations/settings/delete-organization.component.html deleted file mode 100644 index ef4ec15b7e..0000000000 --- a/apps/web/src/app/admin-console/organizations/settings/delete-organization.component.html +++ /dev/null @@ -1,61 +0,0 @@ - diff --git a/apps/web/src/app/admin-console/organizations/settings/index.ts b/apps/web/src/app/admin-console/organizations/settings/index.ts index 289bf3d632..74b356100a 100644 --- a/apps/web/src/app/admin-console/organizations/settings/index.ts +++ b/apps/web/src/app/admin-console/organizations/settings/index.ts @@ -1,2 +1,2 @@ export * from "./organization-settings.module"; -export { DeleteOrganizationComponent } from "./delete-organization.component"; +export { DeleteOrganizationDialogComponent } from "./components/delete-organization-dialog.component"; diff --git a/apps/web/src/app/admin-console/organizations/settings/organization-settings.module.ts b/apps/web/src/app/admin-console/organizations/settings/organization-settings.module.ts index 0b22c66d1e..c5500c6a94 100644 --- a/apps/web/src/app/admin-console/organizations/settings/organization-settings.module.ts +++ b/apps/web/src/app/admin-console/organizations/settings/organization-settings.module.ts @@ -4,18 +4,12 @@ import { LooseComponentsModule, SharedModule } from "../../../shared"; import { PoliciesModule } from "../../organizations/policies"; import { AccountComponent } from "./account.component"; -import { DeleteOrganizationComponent } from "./delete-organization.component"; import { OrganizationSettingsRoutingModule } from "./organization-settings-routing.module"; import { SettingsComponent } from "./settings.component"; import { TwoFactorSetupComponent } from "./two-factor-setup.component"; @NgModule({ imports: [SharedModule, LooseComponentsModule, PoliciesModule, OrganizationSettingsRoutingModule], - declarations: [ - SettingsComponent, - AccountComponent, - DeleteOrganizationComponent, - TwoFactorSetupComponent, - ], + declarations: [SettingsComponent, AccountComponent, TwoFactorSetupComponent], }) export class OrganizationSettingsModule {} diff --git a/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.html b/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.html index 055cdddb38..34a8f21123 100644 --- a/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.html +++ b/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.html @@ -50,4 +50,3 @@ - diff --git a/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts b/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts index 9d632f56c5..1406f08024 100644 --- a/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts +++ b/apps/web/src/app/admin-console/organizations/sponsorships/families-for-enterprise-setup.component.ts @@ -1,9 +1,9 @@ -import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; +import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; -import { Observable, Subject } from "rxjs"; +import { lastValueFrom, Observable, Subject } from "rxjs"; import { first, map, takeUntil } from "rxjs/operators"; -import { ModalService } from "@bitwarden/angular/services/modal.service"; +import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; @@ -11,12 +11,15 @@ import { ValidationService } from "@bitwarden/common/abstractions/validation.ser import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { OrganizationSponsorshipRedeemRequest } from "@bitwarden/common/admin-console/models/request/organization/organization-sponsorship-redeem.request"; -import { PlanType, PlanSponsorshipType } from "@bitwarden/common/billing/enums"; +import { PlanSponsorshipType, PlanType } from "@bitwarden/common/billing/enums"; import { ProductType } from "@bitwarden/common/enums"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { OrganizationPlansComponent } from "../../../billing/settings/organization-plans.component"; -import { DeleteOrganizationComponent } from "../../organizations/settings"; +import { + DeleteOrganizationDialogResult, + openDeleteOrganizationDialog, +} from "../settings/components"; @Component({ selector: "families-for-enterprise-setup", @@ -36,9 +39,6 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy { value.onSuccess.subscribe(this.onOrganizationCreateSuccess.bind(this)); } - @ViewChild("deleteOrganizationTemplate", { read: ViewContainerRef, static: true }) - deleteModalRef: ViewContainerRef; - loading = true; badToken = false; formPromise: Promise; @@ -62,7 +62,7 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy { private syncService: SyncService, private validationService: ValidationService, private organizationService: OrganizationService, - private modalService: ModalService + private dialogService: DialogServiceAbstraction ) {} async ngOnInit() { @@ -136,18 +136,18 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy { this.router.navigate(["/"]); } catch (e) { if (this.showNewOrganization) { - await this.modalService.openViewRef( - DeleteOrganizationComponent, - this.deleteModalRef, - (comp) => { - comp.organizationId = organizationId; - comp.deleteOrganizationRequestType = "InvalidFamiliesForEnterprise"; - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - comp.onSuccess.subscribe(() => { - this.router.navigate(["/"]); - }); - } - ); + const dialog = openDeleteOrganizationDialog(this.dialogService, { + data: { + organizationId: organizationId, + requestType: "InvalidFamiliesForEnterprise", + }, + }); + + const result = await lastValueFrom(dialog.closed); + + if (result === DeleteOrganizationDialogResult.Deleted) { + this.router.navigate(["/"]); + } } this.validationService.showError(this.i18nService.t("sponsorshipTokenHasExpired")); } diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 6a7ae61aa8..955e9b0da9 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -9,7 +9,6 @@ import { SubscriptionRoutingModule } from "../app/billing/settings/subscription- import { flagEnabled, Flags } from "../utils/flags"; import { TrialInitiationComponent } from "./accounts/trial-initiation/trial-initiation.component"; -import { OrganizationModule } from "./admin-console/organizations/organization.module"; import { AcceptFamilySponsorshipComponent } from "./admin-console/organizations/sponsorships/accept-family-sponsorship.component"; import { FamiliesForEnterpriseSetupComponent } from "./admin-console/organizations/sponsorships/families-for-enterprise-setup.component"; import { CreateOrganizationComponent } from "./admin-console/settings/create-organization.component"; @@ -249,7 +248,8 @@ const routes: Routes = [ }, { path: "organizations", - loadChildren: () => OrganizationModule, + loadChildren: () => + import("./admin-console/organizations/organization.module").then((m) => m.OrganizationModule), }, ]; diff --git a/apps/web/src/app/shared/components/user-verification/index.ts b/apps/web/src/app/shared/components/user-verification/index.ts new file mode 100644 index 0000000000..9fe21e309c --- /dev/null +++ b/apps/web/src/app/shared/components/user-verification/index.ts @@ -0,0 +1,3 @@ +export * from "./user-verification.module"; +export * from "./user-verification-prompt.component"; +export * from "./user-verification.component"; diff --git a/apps/web/src/app/components/user-verification-prompt.component.html b/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.html similarity index 100% rename from apps/web/src/app/components/user-verification-prompt.component.html rename to apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.html diff --git a/apps/web/src/app/components/user-verification-prompt.component.ts b/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.ts similarity index 100% rename from apps/web/src/app/components/user-verification-prompt.component.ts rename to apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.ts diff --git a/apps/web/src/app/components/user-verification.component.html b/apps/web/src/app/shared/components/user-verification/user-verification.component.html similarity index 100% rename from apps/web/src/app/components/user-verification.component.html rename to apps/web/src/app/shared/components/user-verification/user-verification.component.html diff --git a/apps/web/src/app/components/user-verification.component.ts b/apps/web/src/app/shared/components/user-verification/user-verification.component.ts similarity index 100% rename from apps/web/src/app/components/user-verification.component.ts rename to apps/web/src/app/shared/components/user-verification/user-verification.component.ts diff --git a/apps/web/src/app/shared/components/user-verification/user-verification.module.ts b/apps/web/src/app/shared/components/user-verification/user-verification.module.ts new file mode 100644 index 0000000000..de6b32f7fe --- /dev/null +++ b/apps/web/src/app/shared/components/user-verification/user-verification.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from "@angular/core"; + +import { SharedModule } from "../../shared.module"; + +import { UserVerificationPromptComponent } from "./user-verification-prompt.component"; +import { UserVerificationComponent } from "./user-verification.component"; + +@NgModule({ + imports: [SharedModule], + declarations: [UserVerificationComponent, UserVerificationPromptComponent], + exports: [UserVerificationComponent, UserVerificationPromptComponent], +}) +export class UserVerificationModule {} diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index a1ba393866..c9f115a273 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -64,8 +64,6 @@ import { TaxInfoComponent } from "../billing/settings/tax-info.component"; import { UserSubscriptionComponent } from "../billing/settings/user-subscription.component"; import { DynamicAvatarComponent } from "../components/dynamic-avatar.component"; import { SelectableAvatarComponent } from "../components/selectable-avatar.component"; -import { UserVerificationPromptComponent } from "../components/user-verification-prompt.component"; -import { UserVerificationComponent } from "../components/user-verification.component"; import { FooterComponent } from "../layouts/footer.component"; import { FrontendLayoutComponent } from "../layouts/frontend-layout.component"; import { NavbarComponent } from "../layouts/navbar.component"; @@ -110,6 +108,7 @@ import { AddEditComponent as OrgAddEditComponent } from "../vault/org-vault/add- import { AttachmentsComponent as OrgAttachmentsComponent } from "../vault/org-vault/attachments.component"; import { CollectionsComponent as OrgCollectionsComponent } from "../vault/org-vault/collections.component"; +import { UserVerificationModule } from "./components/user-verification"; import { SharedModule } from "./shared.module"; // Please do not add to this list of declarations - we should refactor these into modules when doing so makes sense until there are none left. @@ -120,6 +119,7 @@ import { SharedModule } from "./shared.module"; OrganizationCreateModule, RegisterFormModule, ProductSwitcherModule, + UserVerificationModule, ChangeKdfModule, DynamicAvatarComponent, ], @@ -178,7 +178,6 @@ import { SharedModule } from "./shared.module"; GeneratorComponent, PasswordGeneratorHistoryComponent, PasswordRepromptComponent, - UserVerificationPromptComponent, PaymentComponent, PaymentMethodComponent, PreferencesComponent, @@ -224,7 +223,6 @@ import { SharedModule } from "./shared.module"; BillingHistoryViewComponent, UserLayoutComponent, UserSubscriptionComponent, - UserVerificationComponent, VaultTimeoutInputComponent, VerifyEmailComponent, VerifyEmailTokenComponent, @@ -330,7 +328,6 @@ import { SharedModule } from "./shared.module"; BillingHistoryViewComponent, UserLayoutComponent, UserSubscriptionComponent, - UserVerificationComponent, VaultTimeoutInputComponent, VerifyEmailComponent, VerifyEmailTokenComponent, diff --git a/apps/web/src/app/tools/import-export/export.component.ts b/apps/web/src/app/tools/import-export/export.component.ts index 0b3982dcb7..a615eed07d 100644 --- a/apps/web/src/app/tools/import-export/export.component.ts +++ b/apps/web/src/app/tools/import-export/export.component.ts @@ -15,7 +15,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { EncryptedExportType } from "@bitwarden/common/enums"; import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; -import { UserVerificationPromptComponent } from "../../components/user-verification-prompt.component"; +import { UserVerificationPromptComponent } from "../../shared/components/user-verification"; @Component({ selector: "app-export", diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts index 2355f3049f..e6eadd9e92 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts @@ -6,7 +6,7 @@ import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ModalService } from "@bitwarden/angular/services/modal.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; -import { UserVerificationPromptComponent } from "@bitwarden/web-vault/app/components/user-verification-prompt.component"; +import { UserVerificationPromptComponent } from "@bitwarden/web-vault/app/shared/components/user-verification"; import { AccessTokenView } from "../models/view/access-token.view"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts index 74d90c52a6..ee90b4fcb5 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts @@ -9,7 +9,7 @@ import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { UserVerificationPromptComponent } from "@bitwarden/web-vault/app/components/user-verification-prompt.component"; +import { UserVerificationPromptComponent } from "@bitwarden/web-vault/app/shared/components/user-verification"; import { SecretsManagerPortingApiService } from "../services/sm-porting-api.service"; import { SecretsManagerPortingService } from "../services/sm-porting.service"; From b9d3b0aff7b21024784d1bd59ce2df91f56b46f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bispo?= Date: Thu, 25 May 2023 18:32:26 +0100 Subject: [PATCH 38/75] [PM-2398] Fix firefox extension environments bug (#5514) --- .../src/services/config/config.service.ts | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libs/common/src/services/config/config.service.ts b/libs/common/src/services/config/config.service.ts index f17ded9e6c..dba5d1ca09 100644 --- a/libs/common/src/services/config/config.service.ts +++ b/libs/common/src/services/config/config.service.ts @@ -1,4 +1,5 @@ -import { BehaviorSubject, concatMap, from, timer } from "rxjs"; +import { Injectable, OnDestroy } from "@angular/core"; +import { BehaviorSubject, Subject, concatMap, from, takeUntil, timer } from "rxjs"; import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction"; import { ConfigServiceAbstraction } from "../../abstractions/config/config.service.abstraction"; @@ -10,9 +11,11 @@ import { AuthenticationStatus } from "../../auth/enums/authentication-status"; import { FeatureFlag } from "../../enums/feature-flag.enum"; import { ServerConfigData } from "../../models/data/server-config.data"; -export class ConfigService implements ConfigServiceAbstraction { +@Injectable() +export class ConfigService implements ConfigServiceAbstraction, OnDestroy { protected _serverConfig = new BehaviorSubject(null); serverConfig$ = this._serverConfig.asObservable(); + private destroy$ = new Subject(); constructor( private stateService: StateService, @@ -27,11 +30,14 @@ export class ConfigService implements ConfigServiceAbstraction { this._serverConfig.next(serverConfig); }); - this.environmentService.urls - .pipe(concatMap(() => from(this.fetchServerConfig()))) - .subscribe((serverConfig) => { - this._serverConfig.next(serverConfig); - }); + this.environmentService.urls.pipe(takeUntil(this.destroy$)).subscribe(() => { + this.fetchServerConfig(); + }); + } + + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); } async fetchServerConfig(): Promise { From 0fcfe883b5f7eedf98f4d4295d119dab003a0886 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Thu, 25 May 2023 14:17:19 -0400 Subject: [PATCH 39/75] Feature/[PM-1378] - Trusted Device Encryption - Establish trust logic for all clients (#5339) * PM1378 - (1) Create state service methods for securely storing a device symmetric key while following existing pattern of DuckDuckGoKey generation (2) Create makeDeviceKey method on crypto service which leverages the new state service methods for storing the device key. * PM-1378 - Document CSPRNG types w/ comments explaining what they are and when they should be used. * PM-1378 - TODO to add tests for makeDeviceKey method * PM-1378 - Create Devices API service for creating and updating device encrypted master keys + move models according to latest code standards ( I think) * PM-1378 - TODO clean up - DeviceResponse properly moved next to device api service abstraction per ADR 0013 * PM-1378 - CryptoService makeDeviceKey test written * PM-1378 - Tweak crypto service makeDeviceKey test to leverage a describe for the function to better group related code. * PM-1378 - Move known devices call out of API service and into new devices-api.service and update all references. All clients building. * PM-1378 - Comment clean up * PM-1378 - Refactor out master key naming as that is a reserved specific key generated from the MP key derivation process + use same property on request object as back end. * PM-1378 - Missed a use of master key * PM-1378 - More abstraction updates to remove master key. * PM-1378 - Convert crypto service makeDeviceKey into getDeviceKey method to consolidate service logic based on PR feedback * PM-1378- Updating makeDeviceKey --> getDeviceKey tests to match updated code * PM-1378 - Current work on updating establish trusted device logic in light of new encryption mechanisms (introduction of a device asymmetric key pair in order to allow for key rotation while maintaining trusted devices) * PM-1378 - (1) CryptoService.TrustDevice() naming refactors (2) Lots of test additions and tweaks for trustDevice() * PM-1378 - Updated TrustedDeviceKeysRequest names to be consistent across the client side board. * PM-1378 - Move trusted device crypto service methods out of crypto service into new DeviceCryptoService for better single responsibility design * PM-1378 - (1) Add getDeviceByIdentifier endpoint to devices api as will need it later (2) Update TrustedDeviceKeysRequest and DeviceResponse models to match latest server side generic encrypted key names * PM-1378 - PR feedback fix - use JSDOC comments and move from abstraction to implementation * PM-1378 - Per PR feedback, makeDeviceKey should be private - updated tests with workaround. * PM-1378- Per PR feedback, refactored deviceKey to use partialKey dict so we can associate userId with specific device keys. * PM-1378 - Replace deviceId with deviceIdentifier per PR feedback * PM-1378 - Remove unnecessary createTrustedDeviceKey methods * PM-1378 - Update device crypto service to leverage updateTrustedDeviceKeys + update tests * PM-1378 - Update trustDevice logic - (1) Use getEncKey to get user symmetric key as it's the correct method and (2) Attempt to retrieve the userSymKey earlier on and short circuit if it is not found. * PM-1378 - Replace deviceId with deviceIdentifier because they are not the same thing * PM-1378 - Per PR feedback, (1) on web/browser extension, store device key in local storage under account.keys existing structure (2) on desktop, store deviceKey in secure storage. (3) Exempt account.keys.deviceKey from being cleared on account reset * PM-1378 - Desktop testing revealed that I forgot to add userId existence and options reconciliation checks back * PM-1378 - Per discussion with Jake, create DeviceKey custom type which is really just an opaque so we can more easily differentiate between key types. * PM-1378 - Update symmetric-crypto-key.ts opaque DeviceKey to properly setup Opaque type. * PM-1378 - Fix wrong return type for getDeviceKey on DeviceCryptoServiceAbstraction per PR feedback --- .../browser/src/auth/popup/login.component.ts | 6 +- .../desktop/src/auth/login/login.component.ts | 6 +- .../src/services/electron-state.service.ts | 32 ++ .../web/src/app/auth/login/login.component.ts | 6 +- .../src/auth/components/login.component.ts | 6 +- .../src/services/jslib-services.module.ts | 23 ++ libs/common/src/abstractions/api.service.ts | 1 - .../device-crypto.service.abstraction.ts | 8 + .../devices-api.service.abstraction.ts | 14 + .../devices/responses}/device.response.ts | 6 + libs/common/src/abstractions/state.service.ts | 4 +- libs/common/src/models/domain/account.ts | 3 +- .../src/models/domain/symmetric-crypto-key.ts | 5 +- libs/common/src/services/api.service.ts | 8 - .../device-crypto.service.implementation.ts | 85 +++++ .../services/device-crypto.service.spec.ts | 317 ++++++++++++++++++ .../devices-api.service.implementation.ts | 64 ++++ .../requests/trusted-device-keys.request.ts | 7 + libs/common/src/services/state.service.ts | 35 +- libs/common/src/types/csprng.d.ts | 4 + 20 files changed, 613 insertions(+), 27 deletions(-) create mode 100644 libs/common/src/abstractions/device-crypto.service.abstraction.ts create mode 100644 libs/common/src/abstractions/devices/devices-api.service.abstraction.ts rename libs/common/src/{auth/models/response => abstractions/devices/responses}/device.response.ts (65%) create mode 100644 libs/common/src/services/device-crypto.service.implementation.ts create mode 100644 libs/common/src/services/device-crypto.service.spec.ts create mode 100644 libs/common/src/services/devices/devices-api.service.implementation.ts create mode 100644 libs/common/src/services/devices/requests/trusted-device-keys.request.ts diff --git a/apps/browser/src/auth/popup/login.component.ts b/apps/browser/src/auth/popup/login.component.ts index cc48a75e4e..0652070a4d 100644 --- a/apps/browser/src/auth/popup/login.component.ts +++ b/apps/browser/src/auth/popup/login.component.ts @@ -3,9 +3,9 @@ import { FormBuilder } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; import { LoginComponent as BaseLoginComponent } from "@bitwarden/angular/auth/components/login.component"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AppIdService } from "@bitwarden/common/abstractions/appId.service"; import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service"; +import { DevicesApiServiceAbstraction } from "@bitwarden/common/abstractions/devices/devices-api.service.abstraction"; import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; import { FormValidationErrorsService } from "@bitwarden/common/abstractions/formValidationErrors.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -27,7 +27,7 @@ import { flagEnabled } from "../../flags"; export class LoginComponent extends BaseLoginComponent { showPasswordless = false; constructor( - apiService: ApiService, + devicesApiService: DevicesApiServiceAbstraction, appIdService: AppIdService, authService: AuthService, router: Router, @@ -46,7 +46,7 @@ export class LoginComponent extends BaseLoginComponent { loginService: LoginService ) { super( - apiService, + devicesApiService, appIdService, authService, router, diff --git a/apps/desktop/src/auth/login/login.component.ts b/apps/desktop/src/auth/login/login.component.ts index efe09efe73..bd7ff1e73b 100644 --- a/apps/desktop/src/auth/login/login.component.ts +++ b/apps/desktop/src/auth/login/login.component.ts @@ -6,10 +6,10 @@ import { Subject, takeUntil } from "rxjs"; import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component"; import { LoginComponent as BaseLoginComponent } from "@bitwarden/angular/auth/components/login.component"; import { ModalService } from "@bitwarden/angular/services/modal.service"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AppIdService } from "@bitwarden/common/abstractions/appId.service"; import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service"; import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service"; +import { DevicesApiServiceAbstraction } from "@bitwarden/common/abstractions/devices/devices-api.service.abstraction"; import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; import { FormValidationErrorsService } from "@bitwarden/common/abstractions/formValidationErrors.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -52,7 +52,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy { } constructor( - apiService: ApiService, + devicesApiService: DevicesApiServiceAbstraction, appIdService: AppIdService, authService: AuthService, router: Router, @@ -74,7 +74,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy { loginService: LoginService ) { super( - apiService, + devicesApiService, appIdService, authService, router, diff --git a/apps/desktop/src/services/electron-state.service.ts b/apps/desktop/src/services/electron-state.service.ts index b290866dd0..137302c801 100644 --- a/apps/desktop/src/services/electron-state.service.ts +++ b/apps/desktop/src/services/electron-state.service.ts @@ -1,6 +1,11 @@ +import { Utils } from "@bitwarden/common/misc/utils"; import { EncString } from "@bitwarden/common/models/domain/enc-string"; import { GlobalState } from "@bitwarden/common/models/domain/global-state"; import { StorageOptions } from "@bitwarden/common/models/domain/storage-options"; +import { + DeviceKey, + SymmetricCryptoKey, +} from "@bitwarden/common/models/domain/symmetric-crypto-key"; import { StateService as BaseStateService } from "@bitwarden/common/services/state.service"; import { Account } from "../models/account"; @@ -11,6 +16,10 @@ export class ElectronStateService extends BaseStateService implements ElectronStateServiceAbstraction { + private partialKeys = { + deviceKey: "_deviceKey", + }; + async addAccount(account: Account) { // Apply desktop overides to default account values account = new Account(account); @@ -77,4 +86,27 @@ export class ElectronStateService this.reconcileOptions(options, await this.defaultOnDiskOptions()) ); } + + override async getDeviceKey(options?: StorageOptions): Promise { + options = this.reconcileOptions(options, await this.defaultSecureStorageOptions()); + if (options?.userId == null) { + return; + } + + const b64DeviceKey = await this.secureStorageService.get( + `${options.userId}${this.partialKeys.deviceKey}`, + options + ); + + return new SymmetricCryptoKey(Utils.fromB64ToArray(b64DeviceKey).buffer) as DeviceKey; + } + + override async setDeviceKey(value: DeviceKey, options?: StorageOptions): Promise { + options = this.reconcileOptions(options, await this.defaultSecureStorageOptions()); + if (options?.userId == null) { + return; + } + + await this.saveSecureStorageKey(this.partialKeys.deviceKey, value.keyB64, options); + } } diff --git a/apps/web/src/app/auth/login/login.component.ts b/apps/web/src/app/auth/login/login.component.ts index 54f9bd3646..fa5a96cc37 100644 --- a/apps/web/src/app/auth/login/login.component.ts +++ b/apps/web/src/app/auth/login/login.component.ts @@ -5,9 +5,9 @@ import { Subject, takeUntil } from "rxjs"; import { first } from "rxjs/operators"; import { LoginComponent as BaseLoginComponent } from "@bitwarden/angular/auth/components/login.component"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AppIdService } from "@bitwarden/common/abstractions/appId.service"; import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service"; +import { DevicesApiServiceAbstraction } from "@bitwarden/common/abstractions/devices/devices-api.service.abstraction"; import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; import { FormValidationErrorsService } from "@bitwarden/common/abstractions/formValidationErrors.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -41,7 +41,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit, OnDest private destroy$ = new Subject(); constructor( - apiService: ApiService, + devicesApiService: DevicesApiServiceAbstraction, appIdService: AppIdService, authService: AuthService, router: Router, @@ -63,7 +63,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit, OnDest loginService: LoginService ) { super( - apiService, + devicesApiService, appIdService, authService, router, diff --git a/libs/angular/src/auth/components/login.component.ts b/libs/angular/src/auth/components/login.component.ts index 0d7c594e69..e882d93894 100644 --- a/libs/angular/src/auth/components/login.component.ts +++ b/libs/angular/src/auth/components/login.component.ts @@ -3,9 +3,9 @@ import { FormBuilder, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; import { take } from "rxjs/operators"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AppIdService } from "@bitwarden/common/abstractions/appId.service"; import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service"; +import { DevicesApiServiceAbstraction } from "@bitwarden/common/abstractions/devices/devices-api.service.abstraction"; import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; import { AllValidationErrors, @@ -55,7 +55,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit } constructor( - protected apiService: ApiService, + protected devicesApiService: DevicesApiServiceAbstraction, protected appIdService: AppIdService, protected authService: AuthService, protected router: Router, @@ -295,7 +295,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit async getLoginWithDevice(email: string) { try { const deviceIdentifier = await this.appIdService.getAppId(); - const res = await this.apiService.getKnownDevice(email, deviceIdentifier); + const res = await this.devicesApiService.getKnownDevice(email, deviceIdentifier); //ensure the application is not self-hosted this.showLoginWithDevice = res && !this.selfHosted; } catch (e) { diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 7cf75712a0..7ae54c9213 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -10,6 +10,8 @@ import { ConfigApiServiceAbstraction } from "@bitwarden/common/abstractions/conf import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction"; import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service"; import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/abstractions/cryptoFunction.service"; +import { DeviceCryptoServiceAbstraction } from "@bitwarden/common/abstractions/device-crypto.service.abstraction"; +import { DevicesApiServiceAbstraction } from "@bitwarden/common/abstractions/devices/devices-api.service.abstraction"; import { EncryptService } from "@bitwarden/common/abstractions/encrypt.service"; import { EnvironmentService as EnvironmentServiceAbstraction } from "@bitwarden/common/abstractions/environment.service"; import { EventCollectionService as EventCollectionServiceAbstraction } from "@bitwarden/common/abstractions/event/event-collection.service"; @@ -90,6 +92,8 @@ import { ConsoleLogService } from "@bitwarden/common/services/consoleLog.service import { CryptoService } from "@bitwarden/common/services/crypto.service"; import { EncryptServiceImplementation } from "@bitwarden/common/services/cryptography/encrypt.service.implementation"; import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/services/cryptography/multithread-encrypt.service.implementation"; +import { DeviceCryptoService } from "@bitwarden/common/services/device-crypto.service.implementation"; +import { DevicesApiServiceImplementation } from "@bitwarden/common/services/devices/devices-api.service.implementation"; import { EnvironmentService } from "@bitwarden/common/services/environment.service"; import { EventCollectionService } from "@bitwarden/common/services/event/event-collection.service"; import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service"; @@ -351,6 +355,8 @@ import { AbstractThemingService } from "./theming/theming.service.abstraction"; PlatformUtilsServiceAbstraction, LogService, StateServiceAbstraction, + AppIdServiceAbstraction, + DevicesApiServiceAbstraction, ], }, { @@ -656,6 +662,23 @@ import { AbstractThemingService } from "./theming/theming.service.abstraction"; useClass: OrgDomainApiService, deps: [OrgDomainServiceAbstraction, ApiServiceAbstraction], }, + { + provide: DevicesApiServiceAbstraction, + useClass: DevicesApiServiceImplementation, + deps: [ApiServiceAbstraction], + }, + { + provide: DeviceCryptoServiceAbstraction, + useClass: DeviceCryptoService, + deps: [ + CryptoFunctionServiceAbstraction, + CryptoServiceAbstraction, + EncryptService, + StateServiceAbstraction, + AppIdServiceAbstraction, + DevicesApiServiceAbstraction, + ], + }, ], }) export class JslibServicesModule {} diff --git a/libs/common/src/abstractions/api.service.ts b/libs/common/src/abstractions/api.service.ts index 5670a5dc36..2273b29019 100644 --- a/libs/common/src/abstractions/api.service.ts +++ b/libs/common/src/abstractions/api.service.ts @@ -361,7 +361,6 @@ export abstract class ApiService { putDeviceVerificationSettings: ( request: DeviceVerificationRequest ) => Promise; - getKnownDevice: (email: string, deviceIdentifier: string) => Promise; getEmergencyAccessTrusted: () => Promise>; getEmergencyAccessGranted: () => Promise>; diff --git a/libs/common/src/abstractions/device-crypto.service.abstraction.ts b/libs/common/src/abstractions/device-crypto.service.abstraction.ts new file mode 100644 index 0000000000..23b3be967f --- /dev/null +++ b/libs/common/src/abstractions/device-crypto.service.abstraction.ts @@ -0,0 +1,8 @@ +import { DeviceKey } from "../models/domain/symmetric-crypto-key"; + +import { DeviceResponse } from "./devices/responses/device.response"; + +export abstract class DeviceCryptoServiceAbstraction { + trustDevice: () => Promise; + getDeviceKey: () => Promise; +} diff --git a/libs/common/src/abstractions/devices/devices-api.service.abstraction.ts b/libs/common/src/abstractions/devices/devices-api.service.abstraction.ts new file mode 100644 index 0000000000..345b728977 --- /dev/null +++ b/libs/common/src/abstractions/devices/devices-api.service.abstraction.ts @@ -0,0 +1,14 @@ +import { DeviceResponse } from "./responses/device.response"; + +export abstract class DevicesApiServiceAbstraction { + getKnownDevice: (email: string, deviceIdentifier: string) => Promise; + + getDeviceByIdentifier: (deviceIdentifier: string) => Promise; + + updateTrustedDeviceKeys: ( + deviceIdentifier: string, + devicePublicKeyEncryptedUserSymKey: string, + userSymKeyEncryptedDevicePublicKey: string, + deviceKeyEncryptedDevicePrivateKey: string + ) => Promise; +} diff --git a/libs/common/src/auth/models/response/device.response.ts b/libs/common/src/abstractions/devices/responses/device.response.ts similarity index 65% rename from libs/common/src/auth/models/response/device.response.ts rename to libs/common/src/abstractions/devices/responses/device.response.ts index 2770499e81..331df2e16c 100644 --- a/libs/common/src/auth/models/response/device.response.ts +++ b/libs/common/src/abstractions/devices/responses/device.response.ts @@ -7,6 +7,9 @@ export class DeviceResponse extends BaseResponse { identifier: string; type: DeviceType; creationDate: string; + encryptedUserKey: string; + encryptedPublicKey: string; + encryptedPrivateKey: string; constructor(response: any) { super(response); @@ -15,5 +18,8 @@ export class DeviceResponse extends BaseResponse { this.identifier = this.getResponseProperty("Identifier"); this.type = this.getResponseProperty("Type"); this.creationDate = this.getResponseProperty("CreationDate"); + this.encryptedUserKey = this.getResponseProperty("EncryptedUserKey"); + this.encryptedPublicKey = this.getResponseProperty("EncryptedPublicKey"); + this.encryptedPrivateKey = this.getResponseProperty("EncryptedPrivateKey"); } } diff --git a/libs/common/src/abstractions/state.service.ts b/libs/common/src/abstractions/state.service.ts index ac5bb70596..04cfb609fe 100644 --- a/libs/common/src/abstractions/state.service.ts +++ b/libs/common/src/abstractions/state.service.ts @@ -17,7 +17,7 @@ import { ServerConfigData } from "../models/data/server-config.data"; import { Account, AccountSettingsSettings } from "../models/domain/account"; import { EncString } from "../models/domain/enc-string"; import { StorageOptions } from "../models/domain/storage-options"; -import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; +import { DeviceKey, SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; import { WindowState } from "../models/domain/window-state"; import { GeneratedPasswordHistory } from "../tools/generator/password"; import { SendData } from "../tools/send/models/data/send.data"; @@ -163,6 +163,8 @@ export abstract class StateService { setDontShowIdentitiesCurrentTab: (value: boolean, options?: StorageOptions) => Promise; getDuckDuckGoSharedKey: (options?: StorageOptions) => Promise; setDuckDuckGoSharedKey: (value: string, options?: StorageOptions) => Promise; + getDeviceKey: (options?: StorageOptions) => Promise; + setDeviceKey: (value: DeviceKey, options?: StorageOptions) => Promise; getEmail: (options?: StorageOptions) => Promise; setEmail: (value: string, options?: StorageOptions) => Promise; getEmailVerified: (options?: StorageOptions) => Promise; diff --git a/libs/common/src/models/domain/account.ts b/libs/common/src/models/domain/account.ts index a7988d41d7..db98a17b42 100644 --- a/libs/common/src/models/domain/account.ts +++ b/libs/common/src/models/domain/account.ts @@ -23,7 +23,7 @@ import { EventData } from "../data/event.data"; import { ServerConfigData } from "../data/server-config.data"; import { EncString } from "./enc-string"; -import { SymmetricCryptoKey } from "./symmetric-crypto-key"; +import { DeviceKey, SymmetricCryptoKey } from "./symmetric-crypto-key"; export class EncryptionPair { encrypted?: TEncrypted; @@ -107,6 +107,7 @@ export class AccountKeys { string, SymmetricCryptoKey >(); + deviceKey?: DeviceKey; organizationKeys?: EncryptionPair< { [orgId: string]: EncryptedOrganizationKeyData }, Record diff --git a/libs/common/src/models/domain/symmetric-crypto-key.ts b/libs/common/src/models/domain/symmetric-crypto-key.ts index 3bd329dd21..8c9920d131 100644 --- a/libs/common/src/models/domain/symmetric-crypto-key.ts +++ b/libs/common/src/models/domain/symmetric-crypto-key.ts @@ -1,4 +1,4 @@ -import { Jsonify } from "type-fest"; +import { Jsonify, Opaque } from "type-fest"; import { EncryptionType } from "../../enums"; import { Utils } from "../../misc/utils"; @@ -75,3 +75,6 @@ export class SymmetricCryptoKey { return SymmetricCryptoKey.fromString(obj?.keyB64); } } + +// Setup all separate key types as opaque types +export type DeviceKey = Opaque; diff --git a/libs/common/src/services/api.service.ts b/libs/common/src/services/api.service.ts index e02bfb743f..59e3755a04 100644 --- a/libs/common/src/services/api.service.ts +++ b/libs/common/src/services/api.service.ts @@ -1110,14 +1110,6 @@ export class ApiService implements ApiServiceAbstraction { return new DeviceVerificationResponse(r); } - async getKnownDevice(email: string, deviceIdentifier: string): Promise { - const r = await this.send("GET", "/devices/knowndevice", null, false, true, null, (headers) => { - headers.set("X-Device-Identifier", deviceIdentifier); - headers.set("X-Request-Email", Utils.fromUtf8ToUrlB64(email)); - }); - return r as boolean; - } - // Emergency Access APIs async getEmergencyAccessTrusted(): Promise> { diff --git a/libs/common/src/services/device-crypto.service.implementation.ts b/libs/common/src/services/device-crypto.service.implementation.ts new file mode 100644 index 0000000000..ba50e300b4 --- /dev/null +++ b/libs/common/src/services/device-crypto.service.implementation.ts @@ -0,0 +1,85 @@ +import { AppIdService } from "../abstractions/appId.service"; +import { CryptoService } from "../abstractions/crypto.service"; +import { CryptoFunctionService } from "../abstractions/cryptoFunction.service"; +import { DeviceCryptoServiceAbstraction } from "../abstractions/device-crypto.service.abstraction"; +import { DevicesApiServiceAbstraction } from "../abstractions/devices/devices-api.service.abstraction"; +import { DeviceResponse } from "../abstractions/devices/responses/device.response"; +import { EncryptService } from "../abstractions/encrypt.service"; +import { StateService } from "../abstractions/state.service"; +import { DeviceKey, SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; +import { CsprngArray } from "../types/csprng"; + +export class DeviceCryptoService implements DeviceCryptoServiceAbstraction { + constructor( + protected cryptoFunctionService: CryptoFunctionService, + protected cryptoService: CryptoService, + protected encryptService: EncryptService, + protected stateService: StateService, + protected appIdService: AppIdService, + protected devicesApiService: DevicesApiServiceAbstraction + ) {} + + async trustDevice(): Promise { + // Attempt to get user symmetric key + const userSymKey: SymmetricCryptoKey = await this.cryptoService.getEncKey(); + + // If user symmetric key is not found, throw error + if (!userSymKey) { + throw new Error("User symmetric key not found"); + } + + // Generate deviceKey + const deviceKey = await this.makeDeviceKey(); + + // Generate asymmetric RSA key pair: devicePrivateKey, devicePublicKey + const [devicePublicKey, devicePrivateKey] = await this.cryptoFunctionService.rsaGenerateKeyPair( + 2048 + ); + + const [ + devicePublicKeyEncryptedUserSymKey, + userSymKeyEncryptedDevicePublicKey, + deviceKeyEncryptedDevicePrivateKey, + ] = await Promise.all([ + // Encrypt user symmetric key with the DevicePublicKey + this.cryptoService.rsaEncrypt(userSymKey.encKey, devicePublicKey), + + // Encrypt devicePublicKey with user symmetric key + this.encryptService.encrypt(devicePublicKey, userSymKey), + + // Encrypt devicePrivateKey with deviceKey + this.encryptService.encrypt(devicePrivateKey, deviceKey), + ]); + + // Send encrypted keys to server + const deviceIdentifier = await this.appIdService.getAppId(); + return this.devicesApiService.updateTrustedDeviceKeys( + deviceIdentifier, + devicePublicKeyEncryptedUserSymKey.encryptedString, + userSymKeyEncryptedDevicePublicKey.encryptedString, + deviceKeyEncryptedDevicePrivateKey.encryptedString + ); + } + + async getDeviceKey(): Promise { + // Check if device key is already stored + const existingDeviceKey = await this.stateService.getDeviceKey(); + + if (existingDeviceKey != null) { + return existingDeviceKey; + } else { + return this.makeDeviceKey(); + } + } + + private async makeDeviceKey(): Promise { + // Create 512-bit device key + const randomBytes: CsprngArray = await this.cryptoFunctionService.randomBytes(64); + const deviceKey = new SymmetricCryptoKey(randomBytes) as DeviceKey; + + // Save device key in secure storage + await this.stateService.setDeviceKey(deviceKey); + + return deviceKey; + } +} diff --git a/libs/common/src/services/device-crypto.service.spec.ts b/libs/common/src/services/device-crypto.service.spec.ts new file mode 100644 index 0000000000..7e14961cc2 --- /dev/null +++ b/libs/common/src/services/device-crypto.service.spec.ts @@ -0,0 +1,317 @@ +import { mock, mockReset } from "jest-mock-extended"; + +import { AppIdService } from "../abstractions/appId.service"; +import { CryptoFunctionService } from "../abstractions/cryptoFunction.service"; +import { DevicesApiServiceAbstraction } from "../abstractions/devices/devices-api.service.abstraction"; +import { DeviceResponse } from "../abstractions/devices/responses/device.response"; +import { EncryptService } from "../abstractions/encrypt.service"; +import { StateService } from "../abstractions/state.service"; +import { EncryptionType } from "../enums/encryption-type.enum"; +import { EncString } from "../models/domain/enc-string"; +import { DeviceKey, SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; +import { CryptoService } from "../services/crypto.service"; +import { CsprngArray } from "../types/csprng"; + +import { DeviceCryptoService } from "./device-crypto.service.implementation"; + +describe("deviceCryptoService", () => { + let deviceCryptoService: DeviceCryptoService; + + const cryptoFunctionService = mock(); + const cryptoService = mock(); + const encryptService = mock(); + const stateService = mock(); + const appIdService = mock(); + const devicesApiService = mock(); + + beforeEach(() => { + mockReset(cryptoFunctionService); + mockReset(encryptService); + mockReset(stateService); + mockReset(appIdService); + mockReset(devicesApiService); + + deviceCryptoService = new DeviceCryptoService( + cryptoFunctionService, + cryptoService, + encryptService, + stateService, + appIdService, + devicesApiService + ); + }); + + it("instantiates", () => { + expect(deviceCryptoService).not.toBeFalsy(); + }); + + describe("Trusted Device Encryption", () => { + const deviceKeyBytesLength = 64; + const userSymKeyBytesLength = 64; + + describe("getDeviceKey", () => { + let mockRandomBytes: CsprngArray; + let mockDeviceKey: SymmetricCryptoKey; + let existingDeviceKey: DeviceKey; + let stateSvcGetDeviceKeySpy: jest.SpyInstance; + let makeDeviceKeySpy: jest.SpyInstance; + + beforeEach(() => { + mockRandomBytes = new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray; + mockDeviceKey = new SymmetricCryptoKey(mockRandomBytes); + existingDeviceKey = new SymmetricCryptoKey( + new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray + ) as DeviceKey; + + stateSvcGetDeviceKeySpy = jest.spyOn(stateService, "getDeviceKey"); + makeDeviceKeySpy = jest.spyOn(deviceCryptoService as any, "makeDeviceKey"); + }); + + it("gets a device key when there is not an existing device key", async () => { + stateSvcGetDeviceKeySpy.mockResolvedValue(null); + makeDeviceKeySpy.mockResolvedValue(mockDeviceKey); + + const deviceKey = await deviceCryptoService.getDeviceKey(); + + expect(stateSvcGetDeviceKeySpy).toHaveBeenCalledTimes(1); + expect(makeDeviceKeySpy).toHaveBeenCalledTimes(1); + + expect(deviceKey).not.toBeNull(); + expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey); + expect(deviceKey).toEqual(mockDeviceKey); + }); + + it("returns the existing device key without creating a new one when there is an existing device key", async () => { + stateSvcGetDeviceKeySpy.mockResolvedValue(existingDeviceKey); + + const deviceKey = await deviceCryptoService.getDeviceKey(); + + expect(stateSvcGetDeviceKeySpy).toHaveBeenCalledTimes(1); + expect(makeDeviceKeySpy).not.toHaveBeenCalled(); + + expect(deviceKey).not.toBeNull(); + expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey); + expect(deviceKey).toEqual(existingDeviceKey); + }); + }); + + describe("makeDeviceKey", () => { + it("creates a new non-null 64 byte device key, securely stores it, and returns it", async () => { + const mockRandomBytes = new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray; + + const cryptoFuncSvcRandomBytesSpy = jest + .spyOn(cryptoFunctionService, "randomBytes") + .mockResolvedValue(mockRandomBytes); + + const stateSvcSetDeviceKeySpy = jest.spyOn(stateService, "setDeviceKey"); + + // TypeScript will allow calling private methods if the object is of type 'any' + // This is a hacky workaround, but it allows for cleaner tests + const deviceKey = await (deviceCryptoService as any).makeDeviceKey(); + + expect(cryptoFuncSvcRandomBytesSpy).toHaveBeenCalledTimes(1); + expect(cryptoFuncSvcRandomBytesSpy).toHaveBeenCalledWith(deviceKeyBytesLength); + + expect(deviceKey).not.toBeNull(); + expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey); + + expect(stateSvcSetDeviceKeySpy).toHaveBeenCalledTimes(1); + expect(stateSvcSetDeviceKeySpy).toHaveBeenCalledWith(deviceKey); + }); + }); + + describe("trustDevice", () => { + let mockDeviceKeyRandomBytes: CsprngArray; + let mockDeviceKey: DeviceKey; + + let mockUserSymKeyRandomBytes: CsprngArray; + let mockUserSymKey: SymmetricCryptoKey; + + const deviceRsaKeyLength = 2048; + let mockDeviceRsaKeyPair: [ArrayBuffer, ArrayBuffer]; + let mockDevicePrivateKey: ArrayBuffer; + let mockDevicePublicKey: ArrayBuffer; + let mockDevicePublicKeyEncryptedUserSymKey: EncString; + let mockUserSymKeyEncryptedDevicePublicKey: EncString; + let mockDeviceKeyEncryptedDevicePrivateKey: EncString; + + const mockDeviceResponse: DeviceResponse = new DeviceResponse({ + Id: "mockId", + Name: "mockName", + Identifier: "mockIdentifier", + Type: "mockType", + CreationDate: "mockCreationDate", + }); + + const mockDeviceId = "mockDeviceId"; + + let makeDeviceKeySpy: jest.SpyInstance; + let rsaGenerateKeyPairSpy: jest.SpyInstance; + let cryptoSvcGetEncKeySpy: jest.SpyInstance; + let cryptoSvcRsaEncryptSpy: jest.SpyInstance; + let encryptServiceEncryptSpy: jest.SpyInstance; + let appIdServiceGetAppIdSpy: jest.SpyInstance; + let devicesApiServiceUpdateTrustedDeviceKeysSpy: jest.SpyInstance; + + beforeEach(() => { + // Setup all spies and default return values for the happy path + + mockDeviceKeyRandomBytes = new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray; + mockDeviceKey = new SymmetricCryptoKey(mockDeviceKeyRandomBytes) as DeviceKey; + + mockUserSymKeyRandomBytes = new Uint8Array(userSymKeyBytesLength).buffer as CsprngArray; + mockUserSymKey = new SymmetricCryptoKey(mockUserSymKeyRandomBytes); + + mockDeviceRsaKeyPair = [ + new ArrayBuffer(deviceRsaKeyLength), + new ArrayBuffer(deviceRsaKeyLength), + ]; + + mockDevicePublicKey = mockDeviceRsaKeyPair[0]; + mockDevicePrivateKey = mockDeviceRsaKeyPair[1]; + + mockDevicePublicKeyEncryptedUserSymKey = new EncString( + EncryptionType.Rsa2048_OaepSha1_B64, + "mockDevicePublicKeyEncryptedUserSymKey" + ); + + mockUserSymKeyEncryptedDevicePublicKey = new EncString( + EncryptionType.AesCbc256_HmacSha256_B64, + "mockUserSymKeyEncryptedDevicePublicKey" + ); + + mockDeviceKeyEncryptedDevicePrivateKey = new EncString( + EncryptionType.AesCbc256_HmacSha256_B64, + "mockDeviceKeyEncryptedDevicePrivateKey" + ); + + // TypeScript will allow calling private methods if the object is of type 'any' + makeDeviceKeySpy = jest + .spyOn(deviceCryptoService as any, "makeDeviceKey") + .mockResolvedValue(mockDeviceKey); + + rsaGenerateKeyPairSpy = jest + .spyOn(cryptoFunctionService, "rsaGenerateKeyPair") + .mockResolvedValue(mockDeviceRsaKeyPair); + + cryptoSvcGetEncKeySpy = jest + .spyOn(cryptoService, "getEncKey") + .mockResolvedValue(mockUserSymKey); + + cryptoSvcRsaEncryptSpy = jest + .spyOn(cryptoService, "rsaEncrypt") + .mockResolvedValue(mockDevicePublicKeyEncryptedUserSymKey); + + encryptServiceEncryptSpy = jest + .spyOn(encryptService, "encrypt") + .mockImplementation((plainValue, key) => { + if (plainValue === mockDevicePublicKey && key === mockUserSymKey) { + return Promise.resolve(mockUserSymKeyEncryptedDevicePublicKey); + } + if (plainValue === mockDevicePrivateKey && key === mockDeviceKey) { + return Promise.resolve(mockDeviceKeyEncryptedDevicePrivateKey); + } + }); + + appIdServiceGetAppIdSpy = jest + .spyOn(appIdService, "getAppId") + .mockResolvedValue(mockDeviceId); + + devicesApiServiceUpdateTrustedDeviceKeysSpy = jest + .spyOn(devicesApiService, "updateTrustedDeviceKeys") + .mockResolvedValue(mockDeviceResponse); + }); + + it("calls the required methods with the correct arguments and returns a DeviceResponse", async () => { + const response = await deviceCryptoService.trustDevice(); + + expect(makeDeviceKeySpy).toHaveBeenCalledTimes(1); + expect(rsaGenerateKeyPairSpy).toHaveBeenCalledTimes(1); + expect(cryptoSvcGetEncKeySpy).toHaveBeenCalledTimes(1); + + expect(cryptoSvcRsaEncryptSpy).toHaveBeenCalledTimes(1); + expect(encryptServiceEncryptSpy).toHaveBeenCalledTimes(2); + + expect(appIdServiceGetAppIdSpy).toHaveBeenCalledTimes(1); + expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledTimes(1); + expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledWith( + mockDeviceId, + mockDevicePublicKeyEncryptedUserSymKey.encryptedString, + mockUserSymKeyEncryptedDevicePublicKey.encryptedString, + mockDeviceKeyEncryptedDevicePrivateKey.encryptedString + ); + + expect(response).toBeInstanceOf(DeviceResponse); + expect(response).toEqual(mockDeviceResponse); + }); + + it("throws specific error if user symmetric key is not found", async () => { + // setup the spy to return null + cryptoSvcGetEncKeySpy.mockResolvedValue(null); + // check if the expected error is thrown + await expect(deviceCryptoService.trustDevice()).rejects.toThrow( + "User symmetric key not found" + ); + + // reset the spy + cryptoSvcGetEncKeySpy.mockReset(); + + // setup the spy to return undefined + cryptoSvcGetEncKeySpy.mockResolvedValue(undefined); + // check if the expected error is thrown + await expect(deviceCryptoService.trustDevice()).rejects.toThrow( + "User symmetric key not found" + ); + }); + + const methodsToTestForErrorsOrInvalidReturns = [ + { + method: "makeDeviceKey", + spy: () => makeDeviceKeySpy, + errorText: "makeDeviceKey error", + }, + { + method: "rsaGenerateKeyPair", + spy: () => rsaGenerateKeyPairSpy, + errorText: "rsaGenerateKeyPair error", + }, + { + method: "getEncKey", + spy: () => cryptoSvcGetEncKeySpy, + errorText: "getEncKey error", + }, + { + method: "rsaEncrypt", + spy: () => cryptoSvcRsaEncryptSpy, + errorText: "rsaEncrypt error", + }, + { + method: "encryptService.encrypt", + spy: () => encryptServiceEncryptSpy, + errorText: "encryptService.encrypt error", + }, + ]; + + describe.each(methodsToTestForErrorsOrInvalidReturns)( + "trustDevice error handling and invalid return testing", + ({ method, spy, errorText }) => { + // ensures that error propagation works correctly + it(`throws an error if ${method} fails`, async () => { + const methodSpy = spy(); + methodSpy.mockRejectedValue(new Error(errorText)); + await expect(deviceCryptoService.trustDevice()).rejects.toThrow(errorText); + }); + + test.each([null, undefined])( + `throws an error if ${method} returns %s`, + async (invalidValue) => { + const methodSpy = spy(); + methodSpy.mockResolvedValue(invalidValue); + await expect(deviceCryptoService.trustDevice()).rejects.toThrow(); + } + ); + } + ); + }); + }); +}); diff --git a/libs/common/src/services/devices/devices-api.service.implementation.ts b/libs/common/src/services/devices/devices-api.service.implementation.ts new file mode 100644 index 0000000000..aa0d0f0c29 --- /dev/null +++ b/libs/common/src/services/devices/devices-api.service.implementation.ts @@ -0,0 +1,64 @@ +import { DevicesApiServiceAbstraction } from "../../abstractions/devices/devices-api.service.abstraction"; +import { DeviceResponse } from "../../abstractions/devices/responses/device.response"; +import { Utils } from "../../misc/utils"; +import { ApiService } from "../api.service"; + +import { TrustedDeviceKeysRequest } from "./requests/trusted-device-keys.request"; + +export class DevicesApiServiceImplementation implements DevicesApiServiceAbstraction { + constructor(private apiService: ApiService) {} + + async getKnownDevice(email: string, deviceIdentifier: string): Promise { + const r = await this.apiService.send( + "GET", + "/devices/knowndevice", + null, + false, + true, + null, + (headers) => { + headers.set("X-Device-Identifier", deviceIdentifier); + headers.set("X-Request-Email", Utils.fromUtf8ToUrlB64(email)); + } + ); + return r as boolean; + } + + /** + * Get device by identifier + * @param deviceIdentifier - client generated id (not device id in DB) + */ + async getDeviceByIdentifier(deviceIdentifier: string): Promise { + const r = await this.apiService.send( + "GET", + `/devices/identifier/${deviceIdentifier}`, + null, + true, + true + ); + return new DeviceResponse(r); + } + + async updateTrustedDeviceKeys( + deviceIdentifier: string, + devicePublicKeyEncryptedUserSymKey: string, + userSymKeyEncryptedDevicePublicKey: string, + deviceKeyEncryptedDevicePrivateKey: string + ): Promise { + const request = new TrustedDeviceKeysRequest( + devicePublicKeyEncryptedUserSymKey, + userSymKeyEncryptedDevicePublicKey, + deviceKeyEncryptedDevicePrivateKey + ); + + const result = await this.apiService.send( + "PUT", + `/devices/${deviceIdentifier}/keys`, + request, + true, + true + ); + + return new DeviceResponse(result); + } +} diff --git a/libs/common/src/services/devices/requests/trusted-device-keys.request.ts b/libs/common/src/services/devices/requests/trusted-device-keys.request.ts new file mode 100644 index 0000000000..da89de975b --- /dev/null +++ b/libs/common/src/services/devices/requests/trusted-device-keys.request.ts @@ -0,0 +1,7 @@ +export class TrustedDeviceKeysRequest { + constructor( + public encryptedUserKey: string, + public encryptedPublicKey: string, + public encryptedPrivateKey: string + ) {} +} diff --git a/libs/common/src/services/state.service.ts b/libs/common/src/services/state.service.ts index 4a1592e733..dc32c688e3 100644 --- a/libs/common/src/services/state.service.ts +++ b/libs/common/src/services/state.service.ts @@ -35,7 +35,7 @@ import { EncString } from "../models/domain/enc-string"; import { GlobalState } from "../models/domain/global-state"; import { State } from "../models/domain/state"; import { StorageOptions } from "../models/domain/storage-options"; -import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; +import { DeviceKey, SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; import { WindowState } from "../models/domain/window-state"; import { GeneratedPasswordHistory } from "../tools/generator/password"; import { SendData } from "../tools/send/models/data/send.data"; @@ -1054,6 +1054,32 @@ export class StateService< : await this.secureStorageService.save(DDG_SHARED_KEY, value, options); } + async getDeviceKey(options?: StorageOptions): Promise { + options = this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()); + + if (options?.userId == null) { + return null; + } + + const account = await this.getAccount(options); + + return account?.keys?.deviceKey as DeviceKey; + } + + async setDeviceKey(value: DeviceKey, options?: StorageOptions): Promise { + options = this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()); + + if (options?.userId == null) { + return; + } + + const account = await this.getAccount(options); + + account.keys.deviceKey = value; + + await this.saveAccount(account, options); + } + async getEmail(options?: StorageOptions): Promise { return ( await this.getAccount(this.reconcileOptions(options, await this.defaultInMemoryOptions())) @@ -2751,7 +2777,10 @@ export class StateService< // settings persist even on reset, and are not effected by this method protected resetAccount(account: TAccount) { - const persistentAccountInformation = { settings: account.settings }; + const persistentAccountInformation = { + settings: account.settings, + keys: { deviceKey: account.keys.deviceKey }, + }; return Object.assign(this.createAccount(), persistentAccountInformation); } @@ -2830,7 +2859,7 @@ export class StateService< return this.reconcileOptions(options, defaultOptions); } - private async saveSecureStorageKey( + protected async saveSecureStorageKey( key: string, value: T, options?: StorageOptions diff --git a/libs/common/src/types/csprng.d.ts b/libs/common/src/types/csprng.d.ts index b62f8b37a6..ec0a31a9f7 100644 --- a/libs/common/src/types/csprng.d.ts +++ b/libs/common/src/types/csprng.d.ts @@ -1,5 +1,9 @@ import { Opaque } from "type-fest"; +// You would typically use these types when you want to create a type that +// represents an array or string value generated from a +// cryptographic secure pseudorandom number generator (CSPRNG) + type CsprngArray = Opaque; type CsprngString = Opaque; From ffb2dac384170df84f752ca9e6a558ab86434f1a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 02:04:06 +0200 Subject: [PATCH 40/75] Autosync the updated translations (#5516) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/ca/messages.json | 8 +-- apps/desktop/src/locales/pt_PT/messages.json | 60 ++++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index e0d1adf7e5..83731a76f6 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -2253,17 +2253,17 @@ "message": "Actualització de configuració recomanada" }, "region": { - "message": "Region" + "message": "Regió" }, "eu": { - "message": "EU", + "message": "UE", "description": "European Union" }, "us": { - "message": "US", + "message": "EUA", "description": "United States" }, "selfHosted": { - "message": "Self-hosted" + "message": "Autoallotjat" } } diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index e7235d1ed9..554f81d971 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -33,7 +33,7 @@ "message": "Coleções" }, "searchVault": { - "message": "Pesquisar cofre" + "message": "Procurar no cofre" }, "addItem": { "message": "Adicionar item" @@ -272,7 +272,7 @@ "message": "Último nome" }, "fullName": { - "message": "Nome Completo" + "message": "Nome completo" }, "address1": { "message": "Endereço 1" @@ -379,7 +379,7 @@ "message": "Tem a certeza de que deseja sobrescrever o nome de utilizador atual?" }, "noneFolder": { - "message": "Nenhuma pasta", + "message": "Em nenhuma pasta", "description": "This is the folder for uncategorized items" }, "addFolder": { @@ -413,7 +413,7 @@ "message": "Números (0-9)" }, "specialCharacters": { - "message": "Caracteres Especiais (!@#$%^&*)" + "message": "Caracteres especiais (!@#$%^&*)" }, "numWords": { "message": "Número de palavras" @@ -509,7 +509,7 @@ "message": "A palavra-passe mestra é a palavra-passe que utiliza para aceder ao seu cofre. É muito importante que não se esqueça da sua palavra-passe mestra. Não existe maneira de recuperar a palavra-passe no caso de a esquecer." }, "masterPassHintDesc": { - "message": "Uma dica da palavra-passe mestra pode ajudar a lembrar-se da sua palavra-passe se a esquecer." + "message": "Uma dica da palavra-passe mestra pode ajudá-lo a lembrar-se da sua palavra-passe, caso se esqueça dela." }, "reTypeMasterPass": { "message": "Reescreva a palavra-passe mestra" @@ -536,7 +536,7 @@ "message": "Endereço de email inválido." }, "masterPasswordRequired": { - "message": "A palavra-passe mestra é necessária." + "message": "É necessária a palavra-passe mestra." }, "confirmMasterPasswordRequired": { "message": "É necessário reescrever a palavra-passe mestra." @@ -621,7 +621,7 @@ "message": "Enviar código de verificação novamente" }, "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de início de sessão de dois passos" + "message": "Utilizar outro método de verificação de dois passos" }, "insertYubiKey": { "message": "Introduza a sua YubiKey na porta USB do seu computador, depois toque no botão da mesma." @@ -672,13 +672,13 @@ "message": "Início de sessão indisponível" }, "noTwoStepProviders": { - "message": "Esta conta tem o início de sessão de dois passos ativado, no entanto, nenhum dos provedores de início de sessão de dois passos configurados são suportados por este dispositivo." + "message": "Esta conta tem a verificação de dois passos configurada, no entanto, nenhum dos fornecedores de dois passos configurados é suportado por este dispositivo." }, "noTwoStepProviders2": { "message": "Por favor adicione provedores adicionais que são melhor suportados entre dispositivos (como uma aplicação de autenticador)." }, "twoStepOptions": { - "message": "Opções de início de sessão de dois passos" + "message": "Opções de verificação de dois passos" }, "selfHostedEnvironment": { "message": "Ambiente auto-hospedado" @@ -750,7 +750,7 @@ "message": "Adicionar novo item" }, "addNewFolder": { - "message": "Adicionar nova pasta" + "message": "Nova pasta" }, "view": { "message": "Ver" @@ -762,7 +762,7 @@ "message": "A carregar..." }, "lockVault": { - "message": "Bloquear Cofre" + "message": "Bloquear cofre" }, "passwordGenerator": { "message": "Gerador de palavras-passe" @@ -774,7 +774,7 @@ "message": "Help and feedback" }, "getHelp": { - "message": "Obter Ajuda" + "message": "Obter ajuda" }, "fileBugReport": { "message": "Submeter um relatório de bug" @@ -840,10 +840,10 @@ "message": "Palavra-passe mestra inválida" }, "twoStepLoginConfirmation": { - "message": "O início de sessão de dois passos torna a sua conta mais segura ao requerer que verifique o seu início de sessão com outro dispositivo como uma chave de segurança, aplicação de autenticação, SMS, chamada telefónica, ou email. O início de sessão de dois passos pode ser ativado no cofre web bitwarden.com. Pretende visitar o website agora?" + "message": "A verificação de dois passos torna a sua conta mais segura, exigindo que verifique o seu início de sessão com outro dispositivo, como uma chave de segurança, aplicação de autenticação, SMS, chamada telefónica ou e-mail. A verificação de dois passos pode ser configurada em bitwarden.com. Pretende visitar o site agora?" }, "twoStepLogin": { - "message": "Início de sessão de dois passos" + "message": "Verificação de dois passos" }, "vaultTimeout": { "message": "Expiração do cofre" @@ -1078,7 +1078,7 @@ "message": "1 GB de armazenamento encriptado para anexos de ficheiros." }, "premiumSignUpTwoStep": { - "message": "Opções de início de sessão de dois passos adicionais como YubiKey, FIDO U2F, e Duo." + "message": "Opções adicionais de verificação de dois passos, como YubiKey, FIDO U2F e Duo." }, "premiumSignUpReports": { "message": "Higiene de palavras-passe, saúde das contas, e relatórios de brechas de dados para manter o seu cofre seguro." @@ -1453,7 +1453,7 @@ "message": "Tem de selecionar pelo menos uma coleção." }, "premiumUpdated": { - "message": "Atualizou para o premium." + "message": "Atualizou para o Premium." }, "restore": { "message": "Restaurar" @@ -1618,7 +1618,7 @@ "message": "Unfortunately browser integration is currently not supported in the Microsoft Store version." }, "browserIntegrationLinuxDesc": { - "message": "Infelizmente, a integração com o navegador não é, atualmente, suportada para a versão linux." + "message": "Infelizmente, a integração com o navegador não é atualmente suportada na versão Linux." }, "enableBrowserIntegrationFingerprint": { "message": "Require verification for browser integration" @@ -1697,7 +1697,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { - "message": "Data de Expiração" + "message": "Data de expiração" }, "expirationDateDesc": { "message": "If set, access to this Send will expire on the specified date and time.", @@ -1850,7 +1850,7 @@ "message": "Esta ação está protegida. Para continuar, por favor reinsira a sua palavra-passe mestra para verificarmos a sua identidade." }, "updatedMasterPassword": { - "message": "Palavra-passe Mestra Atualizada" + "message": "Palavra-passe mestra atualizada" }, "updateMasterPassword": { "message": "Atualizar palavra-passe mestra" @@ -1922,7 +1922,7 @@ "message": "Uma ou mais políticas da organização impedem que exporte o seu cofre pessoal." }, "addAccount": { - "message": "Adicionar Conta" + "message": "Adicionar conta" }, "removeMasterPassword": { "message": "Remover palavra-passe mestra" @@ -1952,16 +1952,16 @@ "message": "Key connector error: make sure key connector is available and working correctly." }, "lockAllVaults": { - "message": "Bloquear Todos os Cofres" + "message": "Bloquear todos os cofres" }, "accountLimitReached": { - "message": "Não é possível iniciar sessão com mais de 5 contas ao mesmo tempo." + "message": "Não é possível ter a sessão iniciada com mais de 5 contas ao mesmo tempo." }, "accountPreferences": { "message": "Preferências" }, "appPreferences": { - "message": "Definições da Aplicação (Todas as Contas)" + "message": "Definições da aplicação (todas as contas)" }, "accountSwitcherLimitReached": { "message": "Limite de contas atingido. Termine a sessão de uma das contas para adicionar outra." @@ -1976,7 +1976,7 @@ } }, "switchAccount": { - "message": "Mudar de Conta" + "message": "Mudar de conta" }, "options": { "message": "Opções" @@ -1985,10 +1985,10 @@ "message": "A sua sessão expirou. Por favor, volte atrás e tente iniciar sessão novamente." }, "exportingPersonalVaultTitle": { - "message": "A Exportar Cofre Pessoal" + "message": "A exportar cofre pessoal" }, "exportingPersonalVaultDescription": { - "message": "Apenas os itens do cofre pessoal associado ao $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos.", + "message": "Apenas os itens do cofre pessoal associado a $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos.", "placeholders": { "email": { "content": "$1", @@ -2006,7 +2006,7 @@ "message": "Generator" }, "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" + "message": "O que é que gostaria de gerar?" }, "passwordType": { "message": "Password type" @@ -2049,7 +2049,7 @@ "message": "Todos os cofres" }, "searchOrganization": { - "message": "Procurar Organização" + "message": "Procurar organização" }, "searchMyVault": { "message": "Procurar no meu cofre" @@ -2092,13 +2092,13 @@ "message": "A iniciar sessão como" }, "rememberEmail": { - "message": "Relembrar e-mail" + "message": "Lembrar e-mail" }, "notYou": { "message": "Utilizador incorreto?" }, "newAroundHere": { - "message": "Novo por aqui?" + "message": "É novo por cá?" }, "loggingInTo": { "message": "A iniciar sessão em $DOMAIN$", From 0d96997af81fe045840cbb06338839e80b4d5937 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 10:38:57 +0200 Subject: [PATCH 41/75] Autosync the updated translations (#5517) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 23 + apps/web/src/locales/ar/messages.json | 23 + apps/web/src/locales/az/messages.json | 41 +- apps/web/src/locales/be/messages.json | 35 +- apps/web/src/locales/bg/messages.json | 37 +- apps/web/src/locales/bn/messages.json | 23 + apps/web/src/locales/bs/messages.json | 23 + apps/web/src/locales/ca/messages.json | 37 +- apps/web/src/locales/cs/messages.json | 1525 +++++++++++----------- apps/web/src/locales/cy/messages.json | 23 + apps/web/src/locales/da/messages.json | 23 + apps/web/src/locales/de/messages.json | 27 +- apps/web/src/locales/el/messages.json | 23 + apps/web/src/locales/en_GB/messages.json | 23 + apps/web/src/locales/en_IN/messages.json | 23 + apps/web/src/locales/eo/messages.json | 23 + apps/web/src/locales/es/messages.json | 23 + apps/web/src/locales/et/messages.json | 23 + apps/web/src/locales/eu/messages.json | 23 + apps/web/src/locales/fa/messages.json | 83 +- apps/web/src/locales/fi/messages.json | 45 +- apps/web/src/locales/fil/messages.json | 23 + apps/web/src/locales/fr/messages.json | 23 + apps/web/src/locales/gl/messages.json | 23 + apps/web/src/locales/he/messages.json | 23 + apps/web/src/locales/hi/messages.json | 23 + apps/web/src/locales/hr/messages.json | 23 + apps/web/src/locales/hu/messages.json | 37 +- apps/web/src/locales/id/messages.json | 23 + apps/web/src/locales/it/messages.json | 23 + apps/web/src/locales/ja/messages.json | 37 +- apps/web/src/locales/ka/messages.json | 23 + apps/web/src/locales/km/messages.json | 23 + apps/web/src/locales/kn/messages.json | 23 + apps/web/src/locales/ko/messages.json | 23 + apps/web/src/locales/lv/messages.json | 37 +- apps/web/src/locales/ml/messages.json | 23 + apps/web/src/locales/my/messages.json | 23 + apps/web/src/locales/nb/messages.json | 23 + apps/web/src/locales/ne/messages.json | 23 + apps/web/src/locales/nl/messages.json | 23 + apps/web/src/locales/nn/messages.json | 23 + apps/web/src/locales/or/messages.json | 23 + apps/web/src/locales/pl/messages.json | 35 +- apps/web/src/locales/pt_BR/messages.json | 23 + apps/web/src/locales/pt_PT/messages.json | 113 +- apps/web/src/locales/ro/messages.json | 23 + apps/web/src/locales/ru/messages.json | 23 + apps/web/src/locales/si/messages.json | 23 + apps/web/src/locales/sk/messages.json | 23 + apps/web/src/locales/sl/messages.json | 27 +- apps/web/src/locales/sr/messages.json | 31 +- apps/web/src/locales/sr_CS/messages.json | 23 + apps/web/src/locales/sv/messages.json | 23 + apps/web/src/locales/te/messages.json | 23 + apps/web/src/locales/th/messages.json | 23 + apps/web/src/locales/tr/messages.json | 37 +- apps/web/src/locales/uk/messages.json | 49 +- apps/web/src/locales/vi/messages.json | 23 + apps/web/src/locales/zh_CN/messages.json | 25 +- apps/web/src/locales/zh_TW/messages.json | 23 + 61 files changed, 2325 insertions(+), 922 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index e1af3c62ad..7f62c9fd74 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 96e552b584..0564247afe 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 0541dd51dd..072c805723 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -2751,7 +2751,7 @@ } }, "viewCollectionWithName": { - "message": "View collection - $NAME$", + "message": "Kolleksiyaya bax - $NAME$", "placeholders": { "name": { "content": "$1", @@ -2760,7 +2760,7 @@ } }, "editItemWithName": { - "message": "Edit item - $NAME$", + "message": "Elementə düzəliş et - $NAME$", "placeholders": { "name": { "content": "$1", @@ -5227,15 +5227,15 @@ "message": "Açar Bağlayıcı" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "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.", "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": { - "message": "require SSO authentication and single organization policies", + "message": "SSO kimlik təsdiqləməsi və tək təşkilat siyasətləri tələb olunur", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "Açar Bağlayıcı şifrə açmanı quraşdırmaq üçün tələb olunur. Quraşdırma üzrə kömək üçün Bitwarden Dəstək ilə əlaqə saxlayın.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Faktura Sinxronlaşdırma köməyi" }, + "licensePaidFeaturesHelp": { + "message": "Lisenziyalı ödənişli özəlliklər üzrə kömək" + }, + "selfHostGracePeriodHelp": { + "message": "Abunəliyiniz bitdikdən sonra, güncəllənmiş lisenziya faylını təşkilatınıza tətbiq etmək üçün 60 gününüz var. Güzəşt müddəti $GRACE_PERIOD_END_DATE$ bitir.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Lisenziyanı yüklə" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Mövcud üzvlərin öz parollarını dəyişdirməsini tələb et" }, + "region": { + "message": "Bölgə" + }, + "eu": { + "message": "AB", + "description": "European Union" + }, + "us": { + "message": "ABŞ", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Bu layihəni silmək icazəniz yoxdur", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "KDF tənzimləmələrini güncəllə" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Güvənli cihaz şifrələməsi" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Kimlik təsdiqləndikdən sonra üzvlər, cihazlarından saxlanılan açarı istifadə edərək anbar verilənlərinin şifrələrini aça biləcək.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "ana parol sıfırlama siyasəti", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "Bu seçim istifadə edildikdə avto-qeydiyyat ilə işə salınacaq.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index 6c335102a9..4217422b6e 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -5227,11 +5227,11 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Падключыце аўтарызацыю з дапамогай SSO да свайго ўласнага сервера расшыфроўкі ключоў. Пры дапамозе гэтага параметра ўдзельнікам больш непатрэбна будзе выкарыстоўваць свае асноўныя паролі для расшыфроўкі даных сховішча.", "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": { - "message": "require SSO authentication and single organization policies", + "message": "Для наладжвання расшыфроўкі Key Connector патрабуецца аўтэнтыфікацыя SSO", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Дапамога з плацежнай сінхранізацыяй" }, + "licensePaidFeaturesHelp": { + "message": "Даведка па платным ліцэнзійным функцыям" + }, + "selfHostGracePeriodHelp": { + "message": "Пасля таго, як тэрмін дзеяння падпіскі міне ў вас будзе 60 дзён, каб ужыць абноўлены файл ліцэнзіі да вашай арганізацыі. Ільготны перыяд завершыцца: $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Запампаваць ліцэнзію" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Патрабаваць ад існуючых удзельнікаў змены пароляў" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "У вас няма правоў для выдалення гэтага праекта", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "Абнавіце налады KDF" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Шыфраванне даверанай прылады" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Пасля аўтэнтыфікацыі ўдзельнікі расшыфроўваюць даныя сховішча з выкарыстаннем ключа, якія захоўваецца на іх прыладах", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "палітыка скідання асноўнага пароля", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "уключаецца палітыка скідання асноўнага пароля з аўтаматычнай рэгістрацыяй.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index aea467b1ee..61ff37adba 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -5227,15 +5227,15 @@ "message": "Конектор за ключове" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Свържете вписването чрез еднократно удостоверяване със своя собствен сървър за ключове за дешифриране. Така няма да има нужда членовете да използват главната си парола, за да дешифрират данните от трезора си.", "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": { - "message": "require SSO authentication and single organization policies", + "message": "Политиките за еднократно удостоверяване и една организация", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "са необходими, за да бъде настроено шифроването чрез конектор за ключове. Свържете се с поддръжката на Битуорден, ако имате нужда от помощ с настройката.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Помощ относно синхронизирането на лицензи" }, + "licensePaidFeaturesHelp": { + "message": "Помощ относно платените функционалности в лиценза" + }, + "selfHostGracePeriodHelp": { + "message": "След като изтече абонаментът Ви, имате 60 дни да приложите актуализиран лицензионен файл към организацията си. Този период приключва на $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Качване на лиценз" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Задължаване на текущите членове да сменят паролите си" }, + "region": { + "message": "Регион" + }, + "eu": { + "message": "ЕС", + "description": "European Union" + }, + "us": { + "message": "САЩ", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Нямате право за изтриване на този проект", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "Промяна на настройките за KDF" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Шифроване чрез доверено устройство" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "След вписване, членовете ще дешифрират данните от трезорите си чрез ключ, който се съхранява на устройство.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "Политиката за смяна на главната парола", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "с автоматично включване ще бъде активирана при използването на тази настройка.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index d7040e5a4e..75cef1028f 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 863de44265..e9508dc7dd 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 9e90f079a1..af71bb3886 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -5227,15 +5227,15 @@ "message": "Connector de claus" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Connecteu l'inici de sessió amb SSO al vostre servidor de claus de desxifrat autoallotjat. Amb aquesta opció, els membres no hauran d'utilitzar les seves contrasenyes mestres per desxifrar les dades de la caixa forta. El", "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": { - "message": "require SSO authentication and single organization policies", + "message": "requereix autenticació SSO i polítiques d'organització única", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "són necessaris per configurar el desxifrat del connector de claus. Contacteu amb l'assistència de Bitwarden per obtenir ajuda per a la configuració.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Ajuda de sincronització de facturació" }, + "licensePaidFeaturesHelp": { + "message": "Ajuda a les característiques de pagament de la llicència" + }, + "selfHostGracePeriodHelp": { + "message": "Després de que caduque la vostra subscripció, teniu 60 dies per aplicar un fitxer de llicència actualitzat a la vostra organització. El període de gràcia acaba el $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Puja la llicència" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Exigeix que els membres existents canvien les seues contrasenyes" }, + "region": { + "message": "Regió" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "EUA", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "No teniu permisos per suprimir aquest projecte", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "Actualitza la configuració de KDF" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Encriptació de dispositius de confiança" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Una vegada autenticats, els membres desxifraran les dades de la caixa forta mitjançant una clau emmagatzemada al seu dispositiu. El", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "política de restabliment de la contrasenya mestra", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "amb inscripció automàtica s'activarà quan s'utilitze aquesta opció.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index 666f98cee9..056b73fdd5 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -3105,10 +3105,10 @@ "message": "Ověřit e-mail" }, "verifyEmailDesc": { - "message": "Ověřte e-mailovou adresu vašeho účtu pro získání přístupu ke všem funkcím." + "message": "Ověřte e-mailovou adresu Vašeho účtu pro získání přístupu ke všem funkcím." }, "verifyEmailFirst": { - "message": "E-mailová adresa vašeho účtu musí být ověřena." + "message": "E-mailová adresa Vašeho účtu musí být nejprve ověřena." }, "checkInboxForVerification": { "message": "Zkontrolujte svůj e-mail, měli byste obdržet odkaz pro ověření." @@ -3117,37 +3117,37 @@ "message": "Vaše e-mailová adresa byla ověřena" }, "emailVerifiedFailed": { - "message": "Váš e-mail se nepodařilo ověřit. Zkuste odeslat nový ověřovací e-mail." + "message": "Nelze ověřit Váš e-mail. Zkuste odeslat nový ověřovací e-mail." }, "emailVerificationRequired": { - "message": "Je vyžadováno ověření emailu" + "message": "Je vyžadováno ověření e-mailu" }, "emailVerificationRequiredDesc": { - "message": "K použití této funkce je zapotřebí ověření vašeho e-mailu." + "message": "Pro použití této funkce musíte ověřit svůj e-mail." }, "updateBrowser": { - "message": "Aktualizace prohlížeče" + "message": "Aktualizovat prohlížeč" }, "updateBrowserDesc": { - "message": "Používáte nepodporovaný webový prohlížeč. Aplikace nemusí pracovat správně." + "message": "Používáte nepodporovaný webový prohlížeč. Webový trezor nemusí pracovat správně." }, "joinOrganization": { "message": "Přidat se k organizaci" }, "joinOrganizationDesc": { - "message": "Byly jste pozváni do výše uvedené organizace. Pro přijetí pozvánky se musíte přihlásit nebo si založit nový účet." + "message": "Byli jste pozváni do výše uvedené organizace. Chcete-li přijmout pozvánku, musíte se přihlásit nebo vytvořit nový účet na Bitwardenu." }, "inviteAccepted": { - "message": "Pozvánka byla přijata." + "message": "Pozvánka byla přijata" }, "inviteAcceptedDesc": { - "message": "K této organizaci získáte přístup jakmile vám administrátor udělí členství. Až se tak stane, pošleme vám e-mail." + "message": "K této organizaci můžete přistupovat, jakmile správce potvrdí Vaše členství. Až se tak stane, pošleme Vám e-mail." }, "inviteInitAcceptedDesc": { "message": "Nyní můžete přistupovat k této organizaci." }, "inviteAcceptFailed": { - "message": "Pozvánku nelze přijmout. Požádejte administrátora organizace o novou pozvánku." + "message": "Nelze přijmout pozvánku. Požádejte správce organizace o zaslání nové pozvánky." }, "inviteAcceptFailedShort": { "message": "Pozvánku nelze přijmout. $DESCRIPTION$", @@ -3159,40 +3159,40 @@ } }, "rememberEmail": { - "message": "Pamatovat si e-mail" + "message": "Zapamatovat si e-mail" }, "recoverAccountTwoStepDesc": { - "message": "Nemůžete-li přistoupit ke svému účtu pomocí běžné metody dvoufázového přihlášení, můžete použít váš kód pro obnovení dvoufázového přihlášení pro vypnutí všech dvoufázových ověření ve vašem účtu." + "message": "Nemůžete-li přistoupit ke svému účtu pomocí běžné metody dvoufázového přihlášení, můžete pro vypnutí všech dvoufázových ověření ve Vašem účtu použít kód pro obnovení dvoufázového přihlášení." }, "recoverAccountTwoStep": { "message": "Obnovit dvoufázové přihlášení k účtu" }, "twoStepRecoverDisabled": { - "message": "Dvoufázové ověření na vašem účtu bylo vypnuto." + "message": "Dvoufázové ověření na Vašem účtu bylo vypnuto." }, "learnMore": { "message": "Dozvědět se více" }, "deleteRecoverDesc": { - "message": "Zadejte svou e-mailovou adresu pro obnovení a odstranění vašeho účtu." + "message": "Zadejte svou e-mailovou adresu níže pro obnovení a smazání účtu." }, "deleteRecoverEmailSent": { - "message": "Pokud váš účet existuje, zaslali jsme vám e-mail s dalšími pokyny." + "message": "Pokud Váš účet existuje, poslali jsme Vám e-mail s dalšími pokyny." }, "deleteRecoverConfirmDesc": { - "message": "Vyžádali jste si odstranění vašeho Bitwarden účtu. Klepnutím na tlačítko níže akci potvrďte." + "message": "Požádali jste o smazání svého účtu na Bitwardenu. Pro potvrzení použijte tlačítko níže." }, "myOrganization": { - "message": "Má organizace" + "message": "Moje organizace" }, "organizationInfo": { - "message": "Organization info" + "message": "Informace o organizaci" }, "deleteOrganization": { "message": "Smazat organizaci" }, "deletingOrganizationContentWarning": { - "message": "Enter the master password to confirm deletion of $ORGANIZATION$ and all associated data. Vault data in $ORGANIZATION$ includes:", + "message": "Zadejte hlavní heslo pro potvrzení smazání $ORGANIZATION$ a všech souvisejících dat. Data v trezoru v $ORGANIZATION$ zahrnují:", "placeholders": { "organization": { "content": "$1", @@ -3201,7 +3201,7 @@ } }, "deletingOrganizationActiveUserAccountsWarning": { - "message": "User accounts will remain active after deletion but will no longer be associated to this organization." + "message": "Uživatelské účty zůstanou po smazání aktivní, ale již nebudou přiřazeny k této organizaci." }, "deletingOrganizationIsPermanentWarning": { "message": "Smazání $ORGANIZATION$ je trvalé a nevratné.", @@ -3219,28 +3219,28 @@ "message": "Organizace a veškerá související data byla smazána." }, "organizationUpdated": { - "message": "Organizace byla aktualizována." + "message": "Organizace byla uložena" }, "taxInformation": { "message": "Daňové údaje" }, "taxInformationDesc": { - "message": "Pro poskytnutí nebo aktualizaci daňových údajů pro vaše faktury kontaktujte zákaznickou podporu." + "message": "Pro zákazníky v USA je k uspokojení požadavků na daň z prodeje vyžadován kód ZIP, u ostatních zemí můžete volitelně uvést daňové identifikační číslo (DPH/GST) a/nebo adresu, která se objeví na Vašich fakturách." }, "billingPlan": { "message": "Plán", "description": "A billing plan/package. For example: Families, Teams, Enterprise, etc." }, "changeBillingPlan": { - "message": "Změnit plán", + "message": "Aktualizovat plán", "description": "A billing plan/package. For example: Families, Teams, Enterprise, etc." }, "changeBillingPlanUpgrade": { - "message": "Povyšte svůj účet na jiný plán zadáním údajů níže. Ujistěte se prosím, že máte k účtu přidaný platný způsob platby.", + "message": "Aktualizujte Váš účet na jiný plán zadáním údajů níže. Ujistěte se, že máte k účtu přidanou aktivní metodu platby.", "description": "A billing plan/package. For example: Families, Teams, Enterprise, etc." }, "invoiceNumber": { - "message": "Faktura #$NUMBER$", + "message": "Faktura č. $NUMBER$", "description": "ex. Invoice #79C66F0-0001", "placeholders": { "number": { @@ -3259,16 +3259,16 @@ "message": "Ověření bankovního účtu" }, "verifyBankAccountDesc": { - "message": "Provedli jsme dva mikro vklady na váš bankovní účet (může trvat 1 až 2 pracovní dny, než se zobrazí). Zadejte částky vkladů pro ověření vašeho bankovního účtu." + "message": "Provedli jsme dva malé vklady na Váš bankovní účet (může trvat 1 až 2 pracovní dny, než se zobrazí). Zadejte částky vkladů pro ověření Vašeho bankovního účtu." }, "verifyBankAccountInitialDesc": { - "message": "Platba s bankovním účtem je k dispozici pouze zákazníkům ve Spojených státech. Budete vyzváni k ověření vašeho bankovního účtu. V následujících 1-2 pracovních dnech provedeme dva mikro-vklady. Zadejte tyto částky na fakturační stránce organizace pro ověření vašeho bankovního účtu." + "message": "Platba bankovním účtem je k dispozici pouze zákazníkům ve Spojených státech. Budete požádání o ověření Vašeho bankovního účtu. V následujících 1-2 pracovních dnech provedeme dva malé vklady. Pro ověření bankovního účtu zadejte tyto částky na fakturační stránce organizace." }, "verifyBankAccountFailureWarning": { - "message": "Neschopnost ověření vašeho bankovního účtu bude mít za následek zmeškání platby a zrušení vašeho předplatného." + "message": "Selhání ověření bankovního účtu bude mít za následek zmeškanou platbu a pozastavení předplatného." }, "verifiedBankAccount": { - "message": "Bankovní účet byl ověřen." + "message": "Bankovní účet byl ověřen" }, "bankAccount": { "message": "Bankovní účet" @@ -3284,7 +3284,7 @@ } }, "routingNumber": { - "message": "Směrovací číslo", + "message": "Variabilní symbol", "description": "Bank account routing number" }, "accountNumber": { @@ -3297,37 +3297,37 @@ "message": "Typ účtu" }, "bankAccountTypeCompany": { - "message": "Společnost (firma)" + "message": "Firemní" }, "bankAccountTypeIndividual": { - "message": "Individuální (osobní)" + "message": "Osobní" }, "enterInstallationId": { - "message": "Zadejte ID instalace" + "message": "Zadejte ID Vaší instalace" }, "limitSubscriptionDesc": { - "message": "Set a seat limit for your subscription. Once this limit is reached, you will not be able to invite new members." + "message": "Nastavte limit počtu uživatelů pro Vaše předplatné. Jakmile tohoto limitu dosáhnete, nebudete moci pozvat nové členy." }, "maxSeatLimit": { - "message": "Seat Limit (optional)", + "message": "Limit uživatelů (volitelné)", "description": "Upper limit of seats to allow through autoscaling" }, "maxSeatCost": { - "message": "Max potential seat cost" + "message": "Maximální potencialní náklady na uživatele" }, "addSeats": { "message": "Přidat uživatele", "description": "Seat = User Seat" }, "removeSeats": { - "message": "Odstranit uživatele", + "message": "Odebrat uživatele", "description": "Seat = User Seat" }, "subscriptionDesc": { - "message": "Adjustments to your subscription will result in prorated changes to your billing totals. If newly invited users exceed your subscription seats, you will immediately receive a prorated charge for the additional users." + "message": "Úpravy Vašeho předplatného budou mít za následek poměrné změny Vašich fakturačních součtů. Pokud počet nově pozvaných uživatelů překročí počet uživatelů v předplatném, bude Vám okamžitě doúčtován poměrný poplatek za další uživatele." }, "subscriptionUserSeats": { - "message": "Vaše předplatné vám dává prostor pro celkem $COUNT$ uživatelů.", + "message": "Vaše předplatné umožňuje celkem $COUNT$ členů.", "placeholders": { "count": { "content": "$1", @@ -3336,25 +3336,25 @@ } }, "limitSubscription": { - "message": "Limit subscription (optional)" + "message": "Omezit předplatné (volitelné)" }, "subscriptionSeats": { - "message": "Subscription seats" + "message": "Uživatelé v předplatném" }, "subscriptionUpdated": { - "message": "Předplatné aktualizováno" + "message": "Předplatné bylo aktualizováno" }, "additionalOptions": { - "message": "Další možnosti" + "message": "Další volby" }, "additionalOptionsDesc": { - "message": "Pro další pomoc se správou vašeho předplatného kontaktujte prosím zákaznickou podporu." + "message": "Pro další pomoc se správou Vašeho předplatného kontaktujte zákaznickou podporu." }, "subscriptionUserSeatsUnlimitedAutoscale": { - "message": "Adjustments to your subscription will result in prorated changes to your billing totals. If newly invited members exceed your subscription seats, you will immediately receive a prorated charge for the additional members." + "message": "Úpravy Vašeho předplatného budou mít za následek poměrné změny Vašich fakturačních součtů. Pokud počet nově pozvaných členů překročí počet členů v předplatném, bude Vám okamžitě doúčtován poměrný poplatek za další členy." }, "subscriptionUserSeatsLimitedAutoscale": { - "message": "Adjustments to your subscription will result in prorated changes to your billing totals. If newly invited members exceed your subscription seats, you will immediately receive a prorated charge for the additional members until your $MAX$ seat limit is reached.", + "message": "Úpravy Vašeho předplatného budou mít za následek poměrné změny Vašich fakturačních součtů. Pokud počet nově pozvaných členů překročí počet členů v předplatném, bude Vám okamžitě doúčtován poměrný poplatek za další členy dokud nebude dosaženo maximálního limitu: $MAX$.", "placeholders": { "max": { "content": "$1", @@ -3363,7 +3363,7 @@ } }, "subscriptionFreePlan": { - "message": "You cannot invite more than $COUNT$ members without upgrading your plan.", + "message": "Bez aktualizace Vašeho plánu nemůžete pozvat více než $COUNT$ členů.", "placeholders": { "count": { "content": "$1", @@ -3372,7 +3372,7 @@ } }, "subscriptionFamiliesPlan": { - "message": "You cannot invite more than $COUNT$ members without upgrading your plan. Please contact Customer Support to upgrade.", + "message": "Bez aktualizace Vašeho plánu nemůžete pozvat více než $COUNT$ členů. Kontaktujte zákaznickou podporu pro aktualizaci.", "placeholders": { "count": { "content": "$1", @@ -3381,7 +3381,7 @@ } }, "subscriptionSponsoredFamiliesPlan": { - "message": "Your subscription allows for a total of $COUNT$ members. Your plan is sponsored and billed to an external organization.", + "message": "Vaše předplatné umožňuje celkem $COUNT$ členů. Váš plán je sponzorován a účtován externí organizaci.", "placeholders": { "count": { "content": "$1", @@ -3390,7 +3390,7 @@ } }, "subscriptionMaxReached": { - "message": "Adjustments to your subscription will result in prorated changes to your billing totals. You cannot invite more than $COUNT$ members without increasing your subscription seats.", + "message": "Úpravy Vašeho předplatného budou mít za následek poměrné změny Vašich fakturačních součtů. Bez zvýšení počtu členů ve Vašem předplatném nemůžete pozvat více, než $COUNT$ členů.", "placeholders": { "count": { "content": "$1", @@ -3405,13 +3405,13 @@ "message": "Uživatelé k odebrání" }, "seatsAddNote": { - "message": "Přidání uživatelských míst bude mít za následek úpravy fakturačních součtů a okamžité dobití platební metody v souboru. První poplatek bude účtován pro zbytek aktuálního fakturačního cyklu." + "message": "Přidání uživatelů bude mít za následek poměrné změny Vašich fakturačních součtů a okamžité doúčtování pomocí Vaší platební metody. První poplatek se poměrně rozpočítá na zbývající část aktuálního zúčtovacího cyklu." }, "seatsRemoveNote": { - "message": "Odebrání uživatelských míst bude mít za následek úpravy vašich fakturačních součtů, které budou účtovány jako kredity k vašemu dalšímu fakturačnímu poplatku." + "message": "Odebrání uživatelů bude mít za následek úpravu Vašich celkových fakturačních částek, které budou poměrně započítány do příštího vyúčtování." }, "adjustedSeats": { - "message": "Upraveno $AMOUNT$ uživatelských míst.", + "message": "Upraveno na $AMOUNT$ uživatelů.", "placeholders": { "amount": { "content": "$1", @@ -3420,7 +3420,7 @@ } }, "keyUpdated": { - "message": "Klíč byl upraven." + "message": "Klíč byl aktualizován" }, "updateKeyTitle": { "message": "Aktualizovat klíč" @@ -3429,34 +3429,34 @@ "message": "Aktualizovat šifrovací klíč" }, "updateEncryptionKeyShortDesc": { - "message": "Používáte zastaralé šifrovací schéma." + "message": "Aktuálně používáte zastaralé šifrovací schéma." }, "updateEncryptionKeyDesc": { - "message": "Přešli jsme na delší šifrovací klíče, které poskytují vyšší úroveň zabezpečení a přístup k novým funkcím. Aktualizace vašeho šifrovacího klíče je rychlá a snadná. Stačí níže zadat vaše hlavní heslo. Provedení této aktualizace může být v budoucnu povinné." + "message": "Přešli jsme na delší šifrovací klíče, které poskytují vyšší úroveň zabezpečení a přístup k novým funkcím. Aktualizace Vašeho šifrovacího klíče je rychlá a snadná. Stačí níže zadat Vaše hlavní heslo. Provedení této aktualizace může být v budoucnu povinné." }, "updateEncryptionKeyWarning": { - "message": "Po aktualizace šifrovacího klíče dojde k odhlášení a budete se muset opětovně přihlásit do všech Bitwarden aplikací, které aktuálně používáte (např. mobilní aplikace či rozšíření pro prohlížeč). Nezdaří-li se odhlášení a opětovné přihlášení (během něhož bude stažen nový šifrovací klíč), může dojít k poškození údajů. Pokusíme se vás automaticky odhlásit, nicméně, může to chvíli trvat." + "message": "Po aktualizace šifrovacího klíče dojde k odhlášení a budete se muset opětovně přihlásit do všech aplikací Bitwardenu, které aktuálně používáte (např. mobilní aplikace či rozšíření pro prohlížeč). Nezdaří-li se odhlášení a opětovné přihlášení (během něhož bude stažen nový šifrovací klíč), může dojít k poškození dat. Pokusíme se Vás automaticky odhlásit, nicméně, může to chvíli trvat." }, "updateEncryptionKeyExportWarning": { - "message": "Jakékoliv šifrované exporty, které jste uložili, budou také neplatné." + "message": "Jakékoli šifrované exporty, které jste uložili, budou také neplatné." }, "subscription": { - "message": "Odběr" + "message": "Předplatné" }, "loading": { "message": "Načítání" }, "upgrade": { - "message": "Povýšit" + "message": "Aktualizovat" }, "upgradeOrganization": { - "message": "Povýšit organizaci" + "message": "Aktualizovat organizaci" }, "upgradeOrganizationDesc": { - "message": "Tato funkce je nedostupná pro bezplatné organizace. Přejděte na placené členství a odemkněte více funkcí." + "message": "Tato funkce není dostupná pro bezplatné organizace. Přepněte na placenou verzi a odemkněte další funkce." }, "createOrganizationStep1": { - "message": "Vytvoření organizace: Krok 1" + "message": "Vytvořit organizaci: Krok 1" }, "createOrganizationCreatePersonalAccount": { "message": "Před vytvořením organizace si musíte nejdříve vytvořit bezplatný osobní účet." @@ -3468,13 +3468,13 @@ "message": "Nevybrali jste žádné položky." }, "acceptPolicies": { - "message": "Zaškrtnutím tohoto políčka souhlasím s následujícím:" + "message": "Zaškrtnutím tohoto políčka souhlasíte s následujícím:" }, "acceptPoliciesRequired": { - "message": "Podmínky použití a zásady ochrany osobních údajů nebyly odsouhlaseny." + "message": "Podmínky použití a Zásady ochrany osobních údajů nebyly odsouhlaseny." }, "termsOfService": { - "message": "Podmínky služby" + "message": "Podmínky použití" }, "privacyPolicy": { "message": "Zásady ochrany osobních údajů" @@ -3507,10 +3507,10 @@ "message": "Po 4 hodinách" }, "onRefresh": { - "message": "Při obnově karty prohlížeče" + "message": "Při obnovení prohlížeče" }, "dateUpdated": { - "message": "Upraveno", + "message": "Aktualizováno", "description": "ex. Date this item was updated" }, "dateCreated": { @@ -3518,14 +3518,14 @@ "description": "ex. Date this item was created" }, "datePasswordUpdated": { - "message": "Heslo bylo změněno", + "message": "Heslo bylo aktualizováno", "description": "ex. Date this password was updated" }, "organizationIsDisabled": { - "message": "Organizace je zakázána." + "message": "Organizace byla deaktivována" }, "disabledOrganizationFilterError": { - "message": "Položky v zablokovaných organizacích nejsou dostupné. Pro pomoc kontaktujte majitele organizace." + "message": "K položkám v deaktivované organizaci nemáte přístup. Požádejte o pomoc vlastníka organizace." }, "licenseIsExpired": { "message": "Licence vypršela." @@ -3534,7 +3534,7 @@ "message": "Uživatelé byli aktualizováni" }, "selected": { - "message": "Vybrané" + "message": "Vybráno" }, "ownership": { "message": "Vlastnictví" @@ -3562,46 +3562,46 @@ "message": "Slabé hlavní heslo" }, "weakMasterPasswordDesc": { - "message": "Zvolené hlavní heslo je slabé. Pro správnou ochranu účtu Bitwarden byste měli použít silné hlavní heslo (nebo heslovou frázi). Opravdu chcete toto heslo použít?" + "message": "Bylo nalezeno slabé heslo. K zabezpečení Vašeho účtu používejte silné heslo. Opravdu chcete používat toto slabé heslo?" }, "rotateAccountEncKey": { - "message": "Změnit také šifrovací klíč k mému účtu" + "message": "Měnit také šifrovací klíč k mému účtu" }, "rotateEncKeyTitle": { - "message": "Změnit šifrovací klíč" + "message": "Měnit šifrovací klíč" }, "rotateEncKeyConfirmation": { - "message": "Opravdu chcete změnit šifrovací klíč k vašemu účtu?" + "message": "Opravdu chcete měnit šifrovací klíč k Vašemu účtu?" }, "attachmentsNeedFix": { "message": "Tato položka obsahuje staré přílohy, které vyžadují opravu." }, "attachmentFixDesc": { - "message": "Tato stará příloha vyžaduje opravu. Klepnutím zobrazíte více informací." + "message": "Tato stará příloha vyžaduje opravu. Klepněte pro více informací." }, "fix": { "message": "Opravit", "description": "This is a verb. ex. 'Fix The Car'" }, "oldAttachmentsNeedFixDesc": { - "message": "Ve vašem trezoru jsou staré přílohy vyžadující opravu před změnou šifrovacího klíče k vašemu účtu." + "message": "Ve Vašem trezoru jsou staré přílohy vyžadující opravu před změnou šifrovacího klíče k Vašemu účtu." }, "yourAccountsFingerprint": { - "message": "Fráze otisku vašeho účtu", + "message": "Fráze otisku prstu Vašeho účtu", "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." }, "fingerprintEnsureIntegrityVerify": { - "message": "Pro zajištění integrity vašich šifrovacích klíčů proveďte nejprve ověření fráze uživatelského otisku prstu.", + "message": "Pro zajištění integrity Vašich šifrovacích klíčů proveďte nejprve ověření fráze uživatelského otisku prstu.", "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." }, "fingerprintMatchInfo": { - "message": "Please make sure your vault is unlocked and Fingerprint phrase matches the other device." + "message": "Ujistěte se, že je Váš trezor odemčen a fráze otisku prstu se shodují s druhým zařízením." }, "fingerprintPhraseHeader": { - "message": "Fingerprint phrase" + "message": "Fráze otisku prstu" }, "dontAskFingerprintAgain": { - "message": "Již se neptat na ověření fráze otisku účtu (nedoporučeno)", + "message": "Nikdy se neptat na ověření frází otisků prstů pro pozvané uživatele (nedoporučeno)", "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." }, "free": { @@ -3609,44 +3609,44 @@ "description": "Free, as in 'Free beer'" }, "apiKey": { - "message": "API klíč" + "message": "Klíč API" }, "apiKeyDesc": { - "message": "Váš API klíč může být použit pro ověření přístupu k veřejnému Bitwarden API." + "message": "Váš klíč API může být použit pro ověření přístupu k veřejnému API Bitwardenu." }, "apiKeyRotateDesc": { - "message": "Změna API klíče zruší platnost předchozího klíče. API klíč můžete změnit, pokud se domníváte, že aktuální klíč již není bezpečný." + "message": "Změna klíče API zruší platnost předchozího klíče. Klíč API můžete změnit, pokud se domníváte, že aktuální klíč již není bezpečný." }, "apiKeyWarning": { - "message": "Váš API klíč má plný přístup k organizaci. Měl by být uchován v tajnosti." + "message": "Váš klíč API má plný přístup k organizaci. Měl by být uchován v tajnosti." }, "userApiKeyDesc": { - "message": "Váš API klíč může být použit k ověření v Bitwarden CLI." + "message": "Váš klíč API může být použit k ověření v Bitwarden CLI." }, "userApiKeyWarning": { - "message": "Váš API klíč je alternativní ověřovací mechanismus, který by měl být zachován v tajnosti." + "message": "Váš klíč API je alternativní ověřovací mechanismus. Měl by být uchován v tajnosti." }, "oauth2ClientCredentials": { - "message": "OAuth 2.0 klientské údaje", + "message": "Klientské údaje OAuth 2.0", "description": "'OAuth 2.0' is a programming protocol. It should probably not be translated." }, "viewApiKey": { "message": "Zobrazit klíč API" }, "rotateApiKey": { - "message": "Změnit klíč API" + "message": "Měnit klíč API" }, "selectOneCollection": { "message": "Musíte vybrat alespoň jednu kolekci." }, "couldNotChargeCardPayInvoice": { - "message": "Nepodařilo se nám strhnout platbu z vaší karty. Prohlédněte si a zaplaťte nezaplacenou fakturu uvedenou níže." + "message": "Nepodařilo se nám strhnout platbu z Vaší karty. Prohlédněte si a zaplaťte nezaplacenou fakturu uvedenou níže." }, "inAppPurchase": { "message": "Nákup v aplikaci" }, "cannotPerformInAppPurchase": { - "message": "Tuto akci nelze provést při použití platební metody „nákup v aplikaci“." + "message": "Tuto akci nelze provést při použití platební metody \"Nákup v aplikaci\"." }, "manageSubscriptionFromStore": { "message": "Své předplatné musíte spravovat z obchodu, pomocí kterého byl nákup v aplikaci proveden." @@ -3664,19 +3664,19 @@ "message": "Nastavte minimální požadavky pro sílu hlavního hesla." }, "twoStepLoginPolicyTitle": { - "message": "Požadavek dvoufázového přihlášení" + "message": "Požadovat dvoufázové přihlášení" }, "twoStepLoginPolicyDesc": { - "message": "Požadovat po uživatelích nastavení dvoufázového přihlášení pro jejich osobní účty." + "message": "Bude požadovat po uživatelích nastavení dvoufázového přihlášení pro jejich osobní účty." }, "twoStepLoginPolicyWarning": { - "message": "Členové organizace, kteří nemají povoleno dvoufázové přihlášení pro svůj osobní účet, budou odstraněni z organizace a obdrží e-mail, který je o změně informuje." + "message": "Členové organizace, kteří nejsou vlastníky nebo administrátory a kteří nemají povoleno dvoufázové přihlášení pro svůj osobní účet, budou odebráni z organizace a obdrží e-mail, který je o změně informuje." }, "twoStepLoginPolicyUserWarning": { - "message": "Jste členem organizace, která vyžaduje použití dvoufázové přihlášení na vašem uživatelském účtu. Pokud zakážete všechny poskytovatele dvoufázového přihlášení, budete z takovýchto organizací automaticky odebráni." + "message": "Jste členem organizace, která vyžaduje použití dvoufázové přihlášení na Vašem uživatelském účtu. Pokud zakážete všechny poskytovatele dvoufázového přihlášení, budete z takovýchto organizací automaticky odebráni." }, "passwordGeneratorPolicyDesc": { - "message": "Nastavení minimálních požadavků složitosti hesla pro konfiguraci generátoru hesel." + "message": "Nastaví požadavky pro generátor hesel." }, "passwordGeneratorPolicyInEffect": { "message": "Jedna nebo více zásad organizace ovlivňují nastavení generátoru." @@ -3736,10 +3736,10 @@ "message": "Akce při vypršení časového limitu" }, "vaultTimeoutActionLockDesc": { - "message": "Trezor bude uzamčen. Pro opětovný přístup k trezoru bude vyžadováno hlavní heslo." + "message": "Pro přístup k trezoru je nutné hlavní heslo nebo jiná metoda odemknutí." }, "vaultTimeoutActionLogOutDesc": { - "message": "Budete odhlášeni. Pro opětovný přístup k trezoru bude vyžadováno ověření." + "message": "Pro přístup k trezoru je vyžadováno opětovné ověření." }, "lock": { "message": "Zamknout", @@ -3750,7 +3750,7 @@ "description": "Noun: A special folder for holding deleted items that have not yet been permanently deleted" }, "searchTrash": { - "message": "Hledat v koši" + "message": "Prohledat koš" }, "permanentlyDelete": { "message": "Trvale smazat" @@ -3771,7 +3771,7 @@ "message": "Položky byly trvale smazány" }, "permanentlyDeleteSelectedItemsDesc": { - "message": "Vybrané položky ($COUNT$) budou trvale smazány. Opravdu chcete všechny vybrané položky trvale smazat?", + "message": "Vybrali jste $COUNT$ položek k trvalému smazání. Opravdu chcete všechny vybrané položky trvale smazat?", "placeholders": { "count": { "content": "$1", @@ -3780,7 +3780,7 @@ } }, "permanentlyDeletedItemId": { - "message": "Položka $ID$ byla trvale smazána.", + "message": "Položka $ID$ byla trvale smazána", "placeholders": { "id": { "content": "$1", @@ -3810,7 +3810,7 @@ "message": "Obnovit položky" }, "restoreSelectedItemsDesc": { - "message": "Vybrané položky ($COUNT$) budou obnoveny. Opravdu chcete všechny vybrané položky obnovit?", + "message": "Vybrali jste $COUNT$ položek pro obnovení. Opravdu chcete obnovit všechny vybrané položky?", "placeholders": { "count": { "content": "$1", @@ -3819,7 +3819,7 @@ } }, "restoredItemId": { - "message": "Položka $ID$ byla obnovena.", + "message": "Položka $ID$ byla obnovena", "placeholders": { "id": { "content": "$1", @@ -3840,19 +3840,19 @@ "message": "Tyto informace potřebujeme pouze pro výpočet daně a pro finanční přehledy." }, "includeVAT": { - "message": "Zahrnout údaje o DPH (volitelné)" + "message": "Zahrnout údaje o DPH/GST (volitelné)" }, "taxIdNumber": { "message": "DIČ" }, "taxInfoUpdated": { - "message": "Údaje pro DPH aktualizovány." + "message": "Údaje pro DPH byly aktualizovány." }, "setMasterPassword": { "message": "Nastavit hlavní heslo" }, "ssoCompleteRegistration": { - "message": "Chcete-li dokončit přihlášení pomocí SSO, nastavte prosím hlavní přístupové heslo k vašemu trezoru." + "message": "Chcete-li dokončit přihlášení pomocí SSO, nastavte hlavní přístupové heslo k Vašemu trezoru." }, "identifier": { "message": "Identifikátor" @@ -3861,7 +3861,7 @@ "message": "Identifikátor organizace" }, "ssoLogInWithOrgIdentifier": { - "message": "Přihlaste se pomocí přihlašovacího portálu vaší organizace. Chcete-li začít, zadejte prosím identifikátor vaší organizace." + "message": "Přihlaste se pomocí přihlašovacího portálu Vaší organizace. Chcete-li začít, zadejte identifikátor Vaší organizace." }, "enterpriseSingleSignOn": { "message": "Jednotné podnikové přihlášení" @@ -3870,34 +3870,34 @@ "message": "Nyní můžete zavřít tuto kartu a pokračovat v rozšíření." }, "includeAllTeamsFeatures": { - "message": "Všechny funkce Týmů, navíc:" + "message": "Všechny funkce týmů, navíc:" }, "includeSsoAuthentication": { "message": "Podnikové přihlášení prostřednictvím SAML2.0 a OpenID Connect" }, "includeEnterprisePolicies": { - "message": "Podnikové politiky" + "message": "Podnikové zásady" }, "ssoValidationFailed": { "message": "Ověření pomocí SSO selhalo" }, "ssoIdentifierRequired": { - "message": "Je vyžadován identifikátor organizace." + "message": "Je vyžadován SSO identifikátor organizace." }, "ssoIdentifier": { - "message": "SSO identifier" + "message": "SSO identifikátor" }, "ssoIdentifierHint": { - "message": "Provide this ID to your members to login with SSO." + "message": "Pro přihlášení pomocí SSO poskytněte toto ID svým členům." }, "unlinkSso": { - "message": "Odebrat podnikové přihlášení" + "message": "Zrušit propojení s SSO" }, "unlinkSsoConfirmation": { - "message": "Are you sure you want to unlink SSO for this organization?" + "message": "Opravdu chcete zrušit porpojení s SSO pro tuto organizaci?" }, "linkSso": { - "message": "Propojit s podnikovým přihlášením" + "message": "Propojit s SSO" }, "singleOrg": { "message": "Jedna organizace" @@ -3906,28 +3906,28 @@ "message": "Omezí uživatelům možnost připojit se k jiným organizacím." }, "singleOrgBlockCreateMessage": { - "message": "Vaše současná organizace má pravidla, která vám nedovolují připojit se k více než jedné organizaci. Obraťte se na správce organizace nebo se zaregistrujte z jiného účtu Bitwarden." + "message": "Vaše aktuální organizace má pravidla, která Vám nedovolují připojit se k více než jedné organizaci. Obraťte se na administrátory organizace nebo se zaregistrujte z jiného účtu na Bitwardenu." }, "singleOrgPolicyWarning": { - "message": "Členové organizace, kteří nejsou vlastníky nebo správci, a jsou již členy jiné organizace, budou odstraněni z vaší organizace." + "message": "Členové organizace, kteří nejsou vlastníky nebo administrátory a jsou již členy jiné organizace, budou odebrání z Vaší organizace." }, "requireSso": { - "message": "Ověření jednotného přihlášení" + "message": "Vyžadovat ověření jednotného přihlášení" }, "requireSsoPolicyDesc": { - "message": "Vyžaduje přihlášení uživatelů pomocí metody jednotného přihlášení." + "message": "Vyžaduje přihlášení uživatelů pomocí metody jednotného podnikového přihlášení." }, "prerequisite": { "message": "Předpoklady" }, "requireSsoPolicyReq": { - "message": "Před aktivací této politiky musí být povolena politika jednotné organizace." + "message": "Před aktivací této zásady musí být povolena jednotná pravidla organizace." }, "requireSsoPolicyReqError": { - "message": "Jednotná pravidla organizace není povolena." + "message": "Jednotná pravidla organizace nebyla nastavena." }, "requireSsoExemption": { - "message": "Majitelé a správci organizací jsou od prosazování těchto zásad osvobozeni." + "message": "Majitelé a administrátoři organizací jsou od prosazování těchto zásad osvobozeni." }, "sendTypeFile": { "message": "Soubor" @@ -3936,7 +3936,7 @@ "message": "Text" }, "createSend": { - "message": "Vytvořit nový Send", + "message": "Nový Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editSend": { @@ -3944,15 +3944,15 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSend": { - "message": "Send vytvořen", + "message": "Send byl uložen", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { - "message": "Upravený Send", + "message": "Send byl uložen", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletedSend": { - "message": "Send smazán", + "message": "Send byl smazán", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSend": { @@ -3960,7 +3960,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendConfirmation": { - "message": "Jste si jisti, že chcete odstranit tento Send?", + "message": "Opravdu chcete smazat tento Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "whatTypeOfSend": { @@ -3968,14 +3968,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDate": { - "message": "Datum odstranění" + "message": "Datum smazání" }, "deletionDateDesc": { "message": "Tento Send bude trvale smazán v určený datum a čas.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { - "message": "Datum expirace" + "message": "Datum vypršení platnosti" }, "expirationDateDesc": { "message": "Je-li nastaveno, přístup k tomuto Send vyprší v daný datum a čas.", @@ -3989,7 +3989,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "currentAccessCount": { - "message": "Počet aktuálních přístupů" + "message": "Aktuální počet přístupů" }, "sendPasswordDesc": { "message": "Volitelně vyžadovat heslo pro přístup k tomuto Send.", @@ -4003,30 +4003,30 @@ "message": "Zakázáno" }, "revoked": { - "message": "Revoked" + "message": "Odvoláno" }, "sendLink": { - "message": "Odkaz tohoto Send", + "message": "Odkaz pro Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "copySendLink": { - "message": "Zkopírovat odkaz Send", + "message": "Kopírovat odkaz pro Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "removePassword": { - "message": "Odstranit heslo" + "message": "Odebrat heslo" }, "removedPassword": { - "message": "Heslo odstraněno" + "message": "Heslo bylo odebráno" }, "removePasswordConfirmation": { - "message": "Jste si jisti, že chcete odstranit heslo?" + "message": "Opravdu chcete odebrat heslo?" }, "hideEmail": { - "message": "Skrýt mou e-mailovou adresu před příjemci." + "message": "Skrýt moji e-mailovou adresu před příjemci." }, "disableThisSend": { - "message": "Zakažte tento Send, aby k němu nikdo neměl přístup.", + "message": "Deaktivuje tento Send, díky čemuž k němu nebude moci nikdo přistoupit.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "allSends": { @@ -4037,17 +4037,17 @@ "description": "This text will be displayed after a Send has been accessed the maximum amount of times." }, "pendingDeletion": { - "message": "Čeká na smazání" + "message": "Čekání na smazání" }, "expired": { "message": "Vypršela platnost" }, "searchSends": { - "message": "Hledat Sends", + "message": "Prohledat Sends", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendProtectedPassword": { - "message": "Toto Send je chráněno heslem. Pro pokračování zadejte prosím níže heslo.", + "message": "Tento Send je chráněn heslem. Pro pokračování zadejte níže heslo.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendProtectedPasswordDontKnow": { @@ -4055,7 +4055,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendHiddenByDefault": { - "message": "Toto Send je ve výchozím nastavení skryté. Viditelnost můžete přepnout pomocí tlačítka níže.", + "message": "Tento Send je ve výchozím nastavení skrytý. Viditelnost můžete přepnout pomocí tlačítka níže.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "downloadFile": { @@ -4066,36 +4066,36 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "missingSendFile": { - "message": "Soubor přidružený tomuto Send nebyl nalezen.", + "message": "Soubor spojený s tímto Send nebyl nalezen.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "noSendsInList": { - "message": "Nebyly nalezeny žádné Send položky.", + "message": "Žádné Sends k zobrazení.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "emergencyAccess": { "message": "Nouzový přístup" }, "emergencyAccessDesc": { - "message": "Udělit a spravovat nouzový přístup důvěryhodným kontaktům. Důvěryhodné kontakty mohou požádat o přístup k zobrazení nebo převzetí vašeho účtu v případě nouze. Navštivte naši stránku nápovědy pro více informací a podrobností o tom, jak funguje nulové sdílení znalostí." + "message": "Uděluje a spravuje nouzové přístupy důvěryhodným kontaktům. Důvěryhodné kontakty mohou požádat o přístup k zobrazení nebo převzetí Vašeho účtu v případě nouze. Navštivte naši stránku nápovědy pro více informací a podrobností o tom, jak funguje nulové sdílení znalostí." }, "emergencyAccessOwnerWarning": { - "message": "Jste vlastníkem jedné nebo více organizací. Pokud dáte přístup k převzetí nouzovému kontaktu, bude moci po převzetí použít všechna vaše oprávnění jako vlastník." + "message": "Jste vlastníkem jedné nebo více organizací. Pokud udělíte přístup k převzetí nouzovému kontaktu, bude moci po převzetí použít všechna Vaše oprávnění jako vlastník." }, "trustedEmergencyContacts": { "message": "Důvěryhodné nouzové kontakty" }, "noTrustedContacts": { - "message": "Zatím jste nepřidali žádné nouzové kontakty, pozvěte důvěryhodný kontakt, abyste mohli začít." + "message": "Zatím jste nepřidali žádné nouzové kontakty. Abyste mohli začít, pozvěte důvěryhodný kontakt." }, "addEmergencyContact": { "message": "Přidat nouzový kontakt" }, "designatedEmergencyContacts": { - "message": "Určeno jako nouzový kontakt" + "message": "Označen jako nouzový kontakt" }, "noGrantedAccess": { - "message": "Zatím jste nebyl určen jako nouzový kontakt pro nikoho." + "message": "Zatím jste nebyli pro nikoho označeni jako nouzový kontakt." }, "inviteEmergencyContact": { "message": "Pozvat nouzový kontakt" @@ -4104,22 +4104,22 @@ "message": "Upravit nouzový kontakt" }, "inviteEmergencyContactDesc": { - "message": "Pozvěte nový nouzový kontakt zadáním níže uvedené e-mailové adresy účtu Bitwarden. Pokud nemají Bitwarden účet, budou vyzváni k vytvoření nového účtu." + "message": "Pozvěte nový nouzový kontakt zadáním uvedené e-mailové adresy účtu na Bitwardenu. Pokud nemá účet na Bitwardenu, bude vyzván k vytvoření nového účtu." }, "emergencyAccessRecoveryInitiated": { - "message": "Nouzový přístup zahájen" + "message": "Nouzový přístup byl zahájen" }, "emergencyAccessRecoveryApproved": { - "message": "Nouzový přístup schválen" + "message": "Nouzový přístup byl schválen" }, "viewDesc": { - "message": "Může zobrazit všechny položky ve vašem trezoru." + "message": "Může zobrazit všechny položky ve Vašem trezoru." }, "takeover": { "message": "Převzetí" }, "takeoverDesc": { - "message": "Může obnovit váš účet s novým hlavním heslem." + "message": "Může resetovat Váš účet s novým hlavním heslem." }, "waitTime": { "message": "Čas čekání" @@ -4131,7 +4131,7 @@ "message": "1 den" }, "days": { - "message": "$DAYS$ dní", + "message": "$DAYS$ dnů", "placeholders": { "days": { "content": "$1", @@ -4143,7 +4143,7 @@ "message": "Uživatel byl pozván." }, "acceptEmergencyAccess": { - "message": "Byli jste pozváni, abyste se stali nouzovým kontaktem pro výše uvedené uživatele. Chcete-li přijmout pozvánku, musíte se přihlásit nebo vytvořit nový účet Bitwarden." + "message": "Byli jste pozváni, abyste se stali nouzovým kontaktem pro výše uvedeného uživatele. Chcete-li přijmout pozvánku, musíte se přihlásit nebo vytvořit nový účet na Bitwardenu." }, "emergencyInviteAcceptFailed": { "message": "Pozvánku nelze přijmout. Požádejte uživatele o zaslání nové pozvánky." @@ -4158,13 +4158,13 @@ } }, "emergencyInviteAcceptedDesc": { - "message": "Po potvrzení Vaší identity můžete pro tohoto uživatele přistupovat k nouzovým možnostem. Jakmile se tak stane, pošleme vám e-mail." + "message": "Po potvrzení Vaší identity můžete pro tohoto uživatele přistupovat k nouzovým možnostem. Jakmile se tak stane, pošleme Vám e-mail." }, "requestAccess": { "message": "Požádat o přístup" }, "requestAccessConfirmation": { - "message": "Jste si jisti, že chcete požádat o nouzový přístup? Přístup vám bude poskytnut po $WAITTIME$ dnech nebo po ručním schválení žádosti.", + "message": "Opravdu chcete požádat o nouzový přístup? Přístup Vám bude poskytnut po $WAITTIME$ dnech nebo po ručním schválení žádosti.", "placeholders": { "waittime": { "content": "$1", @@ -4173,7 +4173,7 @@ } }, "requestSent": { - "message": "Požádáno o nouzový přístup k $USER$. Jakmile bude možné pokračovat, budeme vás informovat e-mailem.", + "message": "Požádáno o nouzový přístup pro $USER$. Jakmile bude možné pokračovat, budeme Vás informovat e-mailem.", "placeholders": { "user": { "content": "$1", @@ -4188,7 +4188,7 @@ "message": "Odmítnout" }, "approveAccessConfirmation": { - "message": "Jste si jisti, že chcete schválit nouzový přístup? To umožní $USER$ $ACTION$ na váš účet.", + "message": "Opravdu chcete schválit nouzový přístup? To umožní uživateli $USER$ tuto akci ve Vašem účtu: $ACTION$.", "placeholders": { "user": { "content": "$1", @@ -4201,13 +4201,13 @@ } }, "emergencyApproved": { - "message": "Nouzový přístup byl schválen." + "message": "Nouzový přístup byl schválen" }, "emergencyRejected": { - "message": "Nouzový přístup odmítnut" + "message": "Nouzový přístup byl odmítnut" }, "passwordResetFor": { - "message": "Heslo obnoveno pro $USER$. Nyní se můžete přihlásit pomocí nového hesla.", + "message": "Pro $USER$ bylo obnoveno heslo. Nyní se můžete přihlásit pomocí nového hesla.", "placeholders": { "user": { "content": "$1", @@ -4216,59 +4216,59 @@ } }, "personalOwnership": { - "message": "Osobní vlastnictví" + "message": "Odebrat osobní trezor" }, "personalOwnershipPolicyDesc": { - "message": "Vyžaduje po uživatelích uložení položek trezoru do organizace odstraněním možnosti osobního vlastnictví." + "message": "Bude vyžadovat, aby členové ukládali položky do organizace tím, že odeberete možnost osobního trezoru." }, "personalOwnershipExemption": { - "message": "Majitelé a správci organizací jsou od prosazování těchto zásad osvobozeni." + "message": "Majitelé a administrátoři organizací jsou od prosazování těchto zásad osvobozeni." }, "personalOwnershipSubmitError": { - "message": "Vzhledem k podnikovým zásadám je zakázáno ukládat položky do vašeho osobního trezoru. Změňte možnost vlastnictví na organizaci a vyberte z dostupných kolekcí." + "message": "Z důvodu podnikových zásad nemůžete ukládat položky do svého osobního trezoru. Změňte vlastnictví položky na organizaci a poté si vyberte z dostupných kolekcí." }, "disableSend": { - "message": "Deaktivovat Send" + "message": "Odebrat Send" }, "disableSendPolicyDesc": { - "message": "Nedovolit uživatelům vytvářet nebo upravovat Bitwarden Send. Smazání existujícího Send je stále povoleno.", + "message": "Nedovolí členům vytvářet a/nebo upravovat Sends.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "disableSendExemption": { - "message": "Uživatelé organizace, kteří mohou spravovat zásady organizace, jsou osvobozeni od vynucování těchto zásad." + "message": "Uživatelé organizace, kteří mohou spravovat zásady organizace, jsou od prosazování těchto zásad osvobozeni." }, "sendDisabled": { - "message": "Send deaktivován", + "message": "Send odebrán", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { - "message": "Kvůli zásadám podniku můžete odstranit pouze existující Send.", + "message": "Z důvodu podnikových zásad můžete smazat pouze existující Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendOptions": { - "message": "Nastavení Send", + "message": "Volby Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendOptionsPolicyDesc": { - "message": "Nastavte možnosti pro vytváření a úpravy Sendů.", + "message": "Nastaví volby pro vytváření a úpravy Sends.", "description": "'Sends' is a plural noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendOptionsExemption": { - "message": "Uživatelé organizace, kteří mohou spravovat zásady organizace, jsou osvobozeni od vynucování těchto zásad." + "message": "Uživatelé organizace, kteří mohou spravovat zásady organizace, jsou od prosazování těchto zásad osvobozeni." }, "disableHideEmail": { - "message": "Nedovolte uživatelům skrýt svou e-mailovou adresu před příjemci při vytváření nebo úpravách Send.", + "message": "Při vytváření nebo úpravách Send vždy zobrazí e-mailovou adresu člena s příjemci.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendOptionsPolicyInEffect": { - "message": "V současné době platí následující zásady organizace:" + "message": "Aktuálně platí následující zásady organizace:" }, "sendDisableHideEmailInEffect": { "message": "Uživatelé nesmí při vytváření nebo úpravách Send skrýt svou e-mailovou adresu před příjemci.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "modifiedPolicyId": { - "message": "Změněné zásady $ID$.", + "message": "Byly změněny zásady $ID$.", "placeholders": { "id": { "content": "$1", @@ -4286,22 +4286,22 @@ "message": "Vlastní" }, "customDesc": { - "message": "Umožňuje větší kontrolu nad uživatelských oprávnění pro pokročilé konfigurace." + "message": "Uděluje vlastní oprávnění členům" }, "customDescNonEnterpriseStart": { - "message": "Custom roles is an ", + "message": "Vlastní role v ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Custom roles is an enterprise feature. Contact our support team to upgrade your subscription'" }, "customDescNonEnterpriseLink": { - "message": "enterprise feature", + "message": "podnikových funkcích", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Custom roles is an enterprise feature. Contact our support team to upgrade your subscription'" }, "customDescNonEnterpriseEnd": { - "message": ". Contact our support team to upgrade your subscription", + "message": ". Pro aktualizaci Vašeho předplatného kontaktujte náš tým podpory.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Custom roles is an enterprise feature. Contact our support team to upgrade your subscription'" }, "customNonEnterpriseError": { - "message": "To enable custom permissions the organization must be on an Enterprise 2020 plan." + "message": "Pro povolení vlastního oprávnění musí mít organizace plán Enterprise 2020." }, "permissions": { "message": "Oprávnění" @@ -4310,61 +4310,61 @@ "message": "Oprávnění" }, "managerPermissions": { - "message": "Spravovat oprávnění" + "message": "Oprávnění správce" }, "adminPermissions": { - "message": "Admin Permissions" + "message": "Oprávnění administrátora" }, "accessEventLogs": { - "message": "Přístup k logům" + "message": "Přístup k protokolům událostí" }, "accessImportExport": { "message": "Přístup k importu/exportu" }, "accessReports": { - "message": "Přístup k výkazům" + "message": "Přístup k hlášením" }, "missingPermissions": { - "message": "You lack the necessary permissions to perform this action." + "message": "K provedení této akce nemáte potřebná oprávnění." }, "manageAllCollections": { "message": "Správa všech kolekcí" }, "createNewCollections": { - "message": "Create new collections" + "message": "Vytváření nových kolekcí" }, "editAnyCollection": { - "message": "Upravit jakoukoliv kolekci" + "message": "Úprava jakékoli kolekce" }, "deleteAnyCollection": { - "message": "Odstranit jakoukoliv kolekci" + "message": "Smazání jakékoli kolekce" }, "manageAssignedCollections": { "message": "Správa přiřazených kolekcí" }, "editAssignedCollections": { - "message": "Edit assigned collections" + "message": "Úprava přiřazených kolekcí" }, "deleteAssignedCollections": { - "message": "Spravovat přiřazené kolekce" + "message": "Smazání přiřazené kolekce" }, "manageGroups": { - "message": "Spravovat skupiny" + "message": "Správa skupin" }, "managePolicies": { - "message": "Spravovat zásady" + "message": "Správa zásad" }, "manageSso": { - "message": "Spravovat SSO" + "message": "Správa SSO" }, "manageUsers": { - "message": "Spravovat uživatele" + "message": "Správa uživatelů" }, "manageResetPassword": { - "message": "Správa obnovení hesla" + "message": "Správa resetování hesla" }, "disableRequiredError": { - "message": "You must manually turn the $POLICYNAME$ policy before this policy can be turned off.", + "message": "Před vypnutím této zásady musíte ručně změnit zásadu $POLICYNAME$.", "placeholders": { "policyName": { "content": "$1", @@ -4376,13 +4376,13 @@ "message": "Zásady organizace ovlivňují možnosti vlastnictví." }, "personalOwnershipPolicyInEffectImports": { - "message": "An organization policy has blocked importing items into your individual vault." + "message": "Zásady organizace zablokovaly importování položek do Vašeho osobního trezoru." }, "personalOwnershipCheckboxDesc": { - "message": "Zakázat osobní vlastnictví pro uživatele organizace" + "message": "Odebere osobní vlastnictví pro uživatele organizace" }, "textHiddenByDefault": { - "message": "Při přístupu k Send, skrýt text ve výchozím nastavení", + "message": "Při přístupu k Send skrýt text ve výchozím nastavení", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendNameDesc": { @@ -4396,7 +4396,7 @@ "message": "Soubor, který chcete odeslat." }, "copySendLinkOnSave": { - "message": "Zkopírovat odkaz tohoto Send do mé schránky při uložení." + "message": "Zkopírujte odkaz pro sdílení tohoto Send do mé schránky při uložení." }, "sendLinkLabel": { "message": "Odkaz tohoto Send", @@ -4411,14 +4411,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendAccessTaglineLearnMore": { - "message": "Zjistěte více o", + "message": "Dozvědět se více o", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**Learn more about** Bitwarden Send or sign up to try it today.'" }, "sendVaultCardProductDesc": { - "message": "Sdílejte text či soubory s kýmkoliv." + "message": "S kýmkoli můžete sdílet text či soubory." }, "sendVaultCardLearnMore": { - "message": "Zjistěte více", + "message": "Dozvědět se více", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**Learn more**, see how it works, or try it now. '" }, "sendVaultCardSee": { @@ -4446,11 +4446,11 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more about Bitwarden Send or **sign up** to try it today.'" }, "sendAccessTaglineTryToday": { - "message": "abyste to vyzkoušeli již dnes.", + "message": "abyste to vyzkoušeli ještě dnes.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more about Bitwarden Send or sign up to **try it today.**'" }, "sendCreatorIdentifier": { - "message": "Uživatel Bitwarden $USER_IDENTIFIER$ s vámi sdílel následující", + "message": "Uživatel Bitwarden $USER_IDENTIFIER$ s Vámi sdílí následující", "placeholders": { "user_identifier": { "content": "$1", @@ -4459,26 +4459,26 @@ } }, "viewSendHiddenEmailWarning": { - "message": "Uživatel Bitwarden, který vytvořil tento Send, se rozhodl skrýt svou e-mailovou adresu. Před použitím nebo stažením jeho obsahu byste se měli ujistit, že zdroji tohoto odkazu důvěřujete.", + "message": "Uživatel Bitwardenu, který vytvořil tento Send, se rozhodl skrýt svou e-mailovou adresu. Před použitím nebo stažením jeho obsahu byste se měli ujistit, že zdroji tohoto odkazu důvěřujete.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDateIsInvalid": { "message": "Uvedené datum vypršení platnosti není platné." }, "deletionDateIsInvalid": { - "message": "Uvedené datum odstranění není platné." + "message": "Uvedené datum smazání není platné." }, "expirationDateAndTimeRequired": { "message": "Je vyžadováno datum a čas vypršení platnosti." }, "deletionDateAndTimeRequired": { - "message": "Je vyžadováno datum a čas odstranění." + "message": "Je vyžadováno datum a čas smazání." }, "dateParsingError": { - "message": "Došlo k chybě při ukládání dat odstranění a vypršení platnosti." + "message": "Došlo k chybě při ukládání datumů smazání a vypršení platnosti." }, "webAuthnFallbackMsg": { - "message": "Chcete-li ověřit své dvoufaktorové ověření, klikněte na tlačítko níže." + "message": "Pro ověření dvoufaktorového ověření klepněte na tlačítko níže." }, "webAuthnAuthenticate": { "message": "Ověřit WebAuthn" @@ -4487,28 +4487,28 @@ "message": "WebAuthn není v tomto prohlížeči podporován." }, "webAuthnSuccess": { - "message": "WebAuthn úspěšně ověřen!
Tuto kartu můžete zavřít." + "message": "WebAuthn byl úspěšně ověřen! Můžete zavřít tuto kartu." }, "hintEqualsPassword": { - "message": "Nápověda k vašemu heslu nemůže být stejná jako vaše heslo." + "message": "Nápověda k Vašemu heslu nemůže být stejná jako Vaše heslo." }, "enrollPasswordReset": { - "message": "Zapsat do procesu obnovení hesla" + "message": "Zapsat do procesu resetování hesla" }, "enrolledPasswordReset": { - "message": "Zapsáno do procesu obnovení hesla" + "message": "Zapsáno do procesu resetování hesla" }, "withdrawPasswordReset": { - "message": "Odstoupit z obnovení hesla" + "message": "Odstoupit z procesu resetování hesla" }, "enrollPasswordResetSuccess": { - "message": "Zapsání bylo úspěšné!" + "message": "Zápis byl úspěšný!" }, "withdrawPasswordResetSuccess": { "message": "Odstoupení bylo úspěšné!" }, "eventEnrollPasswordReset": { - "message": "Uživatel $ID$ se zapsal do pomoci s obnovením hesla.", + "message": "Uživatel $ID$ se zapsal do procesu s resetováním hesla.", "placeholders": { "id": { "content": "$1", @@ -4517,7 +4517,7 @@ } }, "eventWithdrawPasswordReset": { - "message": "Uživatel $ID$ odstoupil z pomoci s obnovením hesla.", + "message": "Uživatel $ID$ odstoupil z procesu resetování hesla.", "placeholders": { "id": { "content": "$1", @@ -4526,7 +4526,7 @@ } }, "eventAdminPasswordReset": { - "message": "Hlavní heslo uživatele $ID$ obnoveno.", + "message": "Hlavní heslo uživatele $ID$ bylo resetováno.", "placeholders": { "id": { "content": "$1", @@ -4535,7 +4535,7 @@ } }, "eventResetSsoLink": { - "message": "Reset SSO link for user $ID$", + "message": "Resetováno propojení s SSO pro uživatele $ID$", "placeholders": { "id": { "content": "$1", @@ -4544,7 +4544,7 @@ } }, "firstSsoLogin": { - "message": "$ID$ logged in using Sso for the first time", + "message": "Uživatel $ID$ se poprvé přihlásil pomocí SSO", "placeholders": { "id": { "content": "$1", @@ -4553,10 +4553,10 @@ } }, "resetPassword": { - "message": "Obnovit heslo" + "message": "Resetovat heslo" }, "resetPasswordLoggedOutWarning": { - "message": "Pokračováním odhlásíte $NAME$ z aktuální relace, což znamená, že se budou muset znovu přihlásit. Aktivní relace na jiných zařízeních mohou zůstat aktivní až po dobu jedné hodiny.", + "message": "Pokračováním odhlásíte $NAME$ z aktuální relace, což znamená, že se bude muset znovu přihlásit. Aktivní relace na jiných zařízeních mohou zůstat aktivní až po dobu jedné hodiny.", "placeholders": { "name": { "content": "$1", @@ -4571,25 +4571,25 @@ "message": "Jedna nebo více zásad organizace vyžaduje, aby hlavní heslo splňovalo následující požadavky:" }, "resetPasswordSuccess": { - "message": "Heslo bylo úspěšně obnoveno!" + "message": "Heslo bylo úspěšně resetováno!" }, "resetPasswordEnrollmentWarning": { - "message": "Registrace umožní správcům organizace změnit vaše hlavní heslo. Opravdu se chcete zaregistrovat?" + "message": "Zápis umožní správcům organizace změnit Vaše hlavní heslo" }, "resetPasswordPolicy": { - "message": "Obnovení hlavního hesla" + "message": "Resetování hlavního hesla" }, "resetPasswordPolicyDescription": { - "message": "Povolte správcům v organizaci resetovat hlavní heslo uživatelů organizace." + "message": "Povolí administrátorům v organizaci resetovat hlavní hesla uživatelů organizace." }, "resetPasswordPolicyWarning": { - "message": "Uživatelé v organizaci se budou muset sami zaregistrovat nebo být automaticky zaregistrovaní předtím, než budou moct správcové resetovat jejich hlavní heslo." + "message": "Uživatelé v organizaci se budou muset sami zaregistrovat nebo být automaticky zaregistrovaní předtím, než budou moci administrátoři resetovat jejich hlavní heslo." }, "resetPasswordPolicyAutoEnroll": { "message": "Automatická registrace" }, "resetPasswordPolicyAutoEnrollDescription": { - "message": "Jakmile bude jejich pozvání přijato, všichni uživatelé budou automaticky zaregistrováni do obnovení hesla." + "message": "Jakmile bude jejich pozvání přijato, všichni uživatelé budou automaticky zaregistrováni do resetování hesla." }, "resetPasswordPolicyAutoEnrollWarning": { "message": "Uživatelé, kteří jsou již v organizaci, nebudou zpětně zaregistrováni do obnovení hesla. Než budou moci správci obnovit hlavní heslo, budou se muset zaregistrovat sami." @@ -4598,13 +4598,13 @@ "message": "Automaticky zaregistrovat nové uživatele" }, "resetPasswordAutoEnrollInviteWarning": { - "message": "Tato organizace má podnikové zásady, které vás automaticky zaregistrují k obnovení hesla. Registrace umožní správcům organizace změnit vaše hlavní heslo." + "message": "Tato organizace má podnikové zásady, které Vás automaticky zaregistrují k obnovení hesla. Registrace umožní administrátorům organizace změnit Vaše hlavní heslo." }, "resetPasswordOrgKeysError": { "message": "Odpověď klíčů organizace je prázdná" }, "resetPasswordDetailsError": { - "message": "Odpověď na obnovení hesla je prázdná" + "message": "Odpověď na resetování hesla je prázdná" }, "trashCleanupWarning": { "message": "Položky, které byly v koši déle než 30 dní, budou automaticky smazány." @@ -4619,13 +4619,13 @@ "message": "Potvrzení hlavního hesla" }, "passwordConfirmationDesc": { - "message": "Tato akce je chráněna. Chcete-li pokračovat, zadejte znovu vaše hlavní heslo, abychom ověřili vaší totožnost." + "message": "Tato akce je chráněna. Chcete-li pokračovat, zadejte znovu Vaše hlavní heslo pro ověření Vaší totožnosti." }, "reinviteSelected": { - "message": "Znovu odeslat pozvánky" + "message": "Znovu poslat pozvánky" }, "resendNotification": { - "message": "Resend notification" + "message": "Znovu odeslat oznámení" }, "noSelectedUsersApplicable": { "message": "Tuto akci nelze použít na žádného z vybraných uživatelů." @@ -4634,16 +4634,16 @@ "message": "Opravdu chcete odebrat následující uživatele? Proces může trvat několik sekund a nelze jej přerušit ani zrušit." }, "removeOrgUsersConfirmation": { - "message": "When member(s) are removed, they no longer have access to organization data and this action is irreversible. To add the member back to the organization, they must be invited and onboarded again. The process may take a few seconds to complete and cannot be interrupted or canceled." + "message": "Po odebrání člena již nebude mít přístup k údajům organizace a tato akce je nevratná. Chcete-li člena přidat zpět do organizace, je třeba jej znovu pozvat a přijmout. Tento proces může trvat několik sekund a nelze jej přerušit ani zrušit." }, "revokeUsersWarning": { - "message": "When member(s) are revoked, they no longer have access to organization data. To quickly restore member access, go to the Revoked tab. The process may take a few seconds to complete and cannot be interrupted or canceled." + "message": "Po odvolání člena již nebude mít přístup k údajům organizace a tato akce je nevratná. Chcete-li člena rychle přidat zpět do organizace, je třeba jej znovu pozvat a přijmout. Tento proces může trvat několik sekund a nelze jej přerušit ani zrušit." }, "theme": { "message": "Motiv" }, "themeDesc": { - "message": "Vyberte si šablonu pro váš webový trezor." + "message": "Zvolte šablonu pro Váš webový trezor." }, "themeSystem": { "message": "Použít systémový motiv" @@ -4661,22 +4661,22 @@ "message": "Stav hromadné akce" }, "bulkConfirmMessage": { - "message": "Úspěšně potvrzeno." + "message": "Úspěšně potvrzeno" }, "bulkReinviteMessage": { - "message": "Znovu úspěšně pozváno." + "message": "Znovu úspěšně pozváno" }, "bulkRemovedMessage": { - "message": "Úspěšně odstraněno" + "message": "Úspěšně odebráno" }, "bulkRevokedMessage": { - "message": "Revoked organization access successfully" + "message": "Úspěšně odvolán přístup do organizace" }, "bulkRestoredMessage": { - "message": "Restored organization access successfully" + "message": "Úspěšně obnoven přístup do organizace" }, "bulkFilteredMessage": { - "message": "Vyloučené, neplatí pro tuto akci." + "message": "Vyloučené, neplatí pro tuto akci" }, "fingerprint": { "message": "Otisk prstu" @@ -4685,10 +4685,10 @@ "message": "Odebrat uživatele" }, "revokeUsers": { - "message": "Revoke users" + "message": "Odvolat uživatele" }, "restoreUsers": { - "message": "Restore users" + "message": "Obnovit uživatele" }, "error": { "message": "Chyba" @@ -4700,29 +4700,29 @@ "message": "Nastavení poskytovatele" }, "setupProviderLoginDesc": { - "message": "Byli jste pozváni k nastavení nového poskytovatele. Chcete-li pokračovat, musíte se přihlásit nebo vytvořit nový Bitwarden účet." + "message": "Byli jste pozváni k nastavení nového poskytovatele. Chcete-li pokračovat, musíte se přihlásit nebo vytvořit nový účet na Bitwardenu." }, "setupProviderDesc": { - "message": "Pro dokončení nastavení poskytovatele, zadejte prosím níže uvedené údaje. Pokud máte nějaké dotazy, kontaktujte zákaznickou podporu." + "message": "Pro dokončení nastavení poskytovatele, zadejte níže uvedené údaje. Pokud máte nějaké dotazy, kontaktujte zákaznickou podporu." }, "providerName": { - "message": "Jméno poskytovatele" + "message": "Název poskytovatele" }, "providerSetup": { - "message": "Poskytovatel byl vytvořen." + "message": "Poskytovatel byl úspěšně vytvořen" }, "clients": { "message": "Klienti" }, "client": { - "message": "Client", + "message": "Klient", "description": "This is used as a table header to describe which client application created an event log." }, "providerAdmin": { "message": "Administrátor poskytovatele" }, "providerAdminDesc": { - "message": "Uživatel s nejvyšším oprávněním, který může spravovat všechny aspekty vašeho poskytovatele a také přístup a správu klientských organizací." + "message": "Uživatel s nejvyšším oprávněním, který může spravovat všechny aspekty Vašeho poskytovatele a také přístup a správu klientských organizací." }, "serviceUser": { "message": "Servisní uživatel" @@ -4731,31 +4731,31 @@ "message": "Servisní uživatelé mohou přistupovat ke všem klientským organizacím a spravovat je." }, "providerInviteUserDesc": { - "message": "Invite a new user to your Provider by entering their Bitwarden account email address below. If they do not have a Bitwarden account already, they will be prompted to create a new account." + "message": "Pozvěte nového uživatele k Vašemu poskytovateli zadáním e-mailové adresy jeho účtu na Bitwardenu. Pokud ještě nemá účet na Bitwardenu, bude vyzván k vytvoření nového účtu." }, "joinProvider": { - "message": "Join Provider" + "message": "Připojit se k poskytovateli" }, "joinProviderDesc": { - "message": "You've been invited to join the Provider listed above. To accept the invitation, you need to log in or create a new Bitwarden account." + "message": "Byly jste pozváni se připojit k výše uvedenému poskytovateli. Pro přijetí pozvánky se musíte přihlásit nebo si založit nový účet na Bitwardenu." }, "providerInviteAcceptFailed": { - "message": "Unable to accept invitation. Ask a Provider admin to send a new invitation." + "message": "Nelze přijmout pozvánku. Požádejte administrátora poskytovatele o zaslání nové pozvánky." }, "providerInviteAcceptedDesc": { - "message": "You can access this Provider once an administrator confirms your membership. We'll send you an email when that happens." + "message": "K tomuto poskytovateli můžete přistupovat jakmile administrátor potvrdí Vaše členství. Až se tak stane, pošleme Vám e-mail." }, "providerUsersNeedConfirmed": { - "message": "You have users that have accepted their invitation, but still need to be confirmed. Users will not have access to the Provider until they are confirmed." + "message": "Někteří uživatelé přijali pozvánku, ale nejdříve musí být potvrzeni. Dokud nedojde k potvrzení, nebudou mít tito uživatelé přístup k poskytovateli." }, "provider": { "message": "Poskytovatel" }, "newClientOrganization": { - "message": "New client organization" + "message": "Nová organizace klienta" }, "newClientOrganizationDesc": { - "message": "Create a new client organization that will be associated with you as the Provider. You will be able to access and manage this organization." + "message": "Vytvoří novou organizaci klienta, která bude spojena s Vámi jako poskytovatel. Budete mít přístup a budete moci spravovat tuto organizaci." }, "addExistingOrganization": { "message": "Přidat existující organizaci" @@ -4764,7 +4764,7 @@ "message": "Můj poskytovatel" }, "addOrganizationConfirmation": { - "message": "Are you sure you want to add $ORGANIZATION$ as a client to $PROVIDER$?", + "message": "Opravdu chcete přidat $ORGANIZATION$ jako klienta pro $PROVIDER$?", "placeholders": { "organization": { "content": "$1", @@ -4777,10 +4777,10 @@ } }, "organizationJoinedProvider": { - "message": "Organization was successfully added to the Provider" + "message": "Organizace byla úspěšně přidána k poskytovateli" }, "accessingUsingProvider": { - "message": "Accessing organization using Provider $PROVIDER$", + "message": "Přistupování k organizaci pomocí poskytovatele $PROVIDER$", "placeholders": { "provider": { "content": "$1", @@ -4789,13 +4789,13 @@ } }, "providerIsDisabled": { - "message": "Provider suspended" + "message": "Poskytovatel byl deaktivován" }, "providerUpdated": { - "message": "Provider saved" + "message": "Poskytovatel byl uložen" }, "yourProviderIs": { - "message": "Your Provider is $PROVIDER$. They have administrative and billing privileges for your organization.", + "message": "Váš poskytovatel je $PROVIDER$. Ma administrátorská a fakturační oprávnění pro Vaši organizaci.", "placeholders": { "provider": { "content": "$1", @@ -4804,7 +4804,7 @@ } }, "detachedOrganization": { - "message": "The organization $ORGANIZATION$ has been detached from your Provider.", + "message": "Organizace $ORGANIZATION$ byla oddělena od Vašeho poskytovatele.", "placeholders": { "organization": { "content": "$1", @@ -4813,22 +4813,22 @@ } }, "detachOrganizationConfirmation": { - "message": "Are you sure you want to detach this organization? The organization will continue to exist but will no longer be managed by the Provider." + "message": "Opravdu chcete oddělit tuto organizaci? Organizace bude nadále existovat, ale již nebude spravována poskytovatelem." }, "add": { "message": "Přidat" }, "updatedMasterPassword": { - "message": "Hlavní heslo aktualizováno" + "message": "Hlavní heslo bylo aktualizováno" }, "updateMasterPassword": { "message": "Aktualizovat hlavní heslo" }, "updateMasterPasswordWarning": { - "message": "Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "Administrátor v organizaci nedávno změnil Vaše hlavní heslo. Pro přístup k trezoru jej nyní musíte změnit. Pokračování Vás odhlásí z Vaší aktuální relace a bude nutné se znovu přihlásit. Aktivní relace na jiných zařízeních mohou zůstat aktivní až po dobu jedné hodiny." }, "masterPasswordInvalidWarning": { - "message": "Your master password does not meet the policy requirements of this organization. In order to join the organization, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "Vaše hlavní heslo nesplňuje zásady Vaší organizace. Pro přístup k organizaci musíte nyní aktualizovat své hlavní heslo. Pokračování Vás odhlásí z Vaší aktuální relace a bude nutné se přihlásit. Aktivní relace na jiných zařízeních mohou zůstat aktivní až po dobu jedné hodiny." }, "updateWeakMasterPasswordWarning": { "message": "Vaše hlavní heslo nesplňuje jednu nebo více zásad Vaší organizace. Pro přístup k trezoru musíte nyní aktualizovat své hlavní heslo. Pokračování Vás odhlásí z Vaší aktuální relace a bude nutné se přihlásit. Aktivní relace na jiných zařízeních mohou zůstat aktivní až po dobu jedné hodiny." @@ -4837,22 +4837,22 @@ "message": "Časový limit trezoru" }, "maximumVaultTimeoutDesc": { - "message": "Nastavení maximálního časového limitu trezoru pro všechny uživatele." + "message": "Nastaví maximální časový limit trezoru pro všechny uživatele." }, "maximumVaultTimeoutLabel": { - "message": "Maximum vault timeout" + "message": "Maximální časový limit trezoru" }, "invalidMaximumVaultTimeout": { - "message": "Invalid maximum vault timeout." + "message": "Neplatný maximální časový limit trezoru." }, "hours": { - "message": "Hodin" + "message": "Hodiny" }, "minutes": { - "message": "Minut" + "message": "Minuty" }, "vaultTimeoutPolicyInEffect": { - "message": "Your organization policies have set your maximum allowed vault timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "message": "Zásady Vaší organizace nastavily maximální povolený časový limit trezoru na $HOURS$ hodin a $MINUTES$ minut.", "placeholders": { "hours": { "content": "$1", @@ -4891,205 +4891,205 @@ } }, "customVaultTimeout": { - "message": "Custom vault timeout" + "message": "Vlastní časový limit trezoru" }, "vaultTimeoutToLarge": { - "message": "Your vault timeout exceeds the restriction set by your organization." + "message": "Časový limit Vašeho trezoru překračuje omezení stanovená Vaší organizací." }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "Minimální vlastní časový limit je 1 minuta." }, "vaultTimeoutRangeError": { - "message": "Vault timeout is not within allowed range." + "message": "Časový limit trezoru není v rámci povoleného rozsahu." }, "disablePersonalVaultExport": { - "message": "Remove individual vault export" + "message": "Odebrat osobní export trezoru" }, "disablePersonalVaultExportDesc": { - "message": "Do not allow members to export their individual vault data." + "message": "Nedovolí, aby členové exportovali svá osobní data trezoru." }, "vaultExportDisabled": { - "message": "Vault export removed" + "message": "Export trezoru byl odebrán" }, "personalVaultExportPolicyInEffect": { - "message": "One or more organization policies prevents you from exporting your individual vault." + "message": "Jedna nebo více zásad organizace Vám brání v exportu Vašeho osobního trezoru." }, "activateAutofill": { - "message": "Activate auto-fill" + "message": "Aktivovat automatické vyplnění" }, "activateAutofillPolicyDesc": { "message": "Aktivuje automatické vyplnění při načítání stránky pro rozšíření prohlížeče pro všechny existující i nové členy." }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Kompromitované nebo nedůvěryhodné webové stránky mohou zneužívat automatické vyplňování při načítání stránky." }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Více informací o automatickém vyplňování" }, "selectType": { - "message": "Select SSO type" + "message": "Zvolte typ SSO" }, "type": { "message": "Typ" }, "openIdConnectConfig": { - "message": "OpenID connect configuration" + "message": "Konfigurace připojení OpenID" }, "samlSpConfig": { - "message": "SAML service provider configuration" + "message": "Konfigurace servisního poskytovatele SAML" }, "samlIdpConfig": { - "message": "SAML identity provider configuration" + "message": "Konfigurace poskytovatele identit SAML" }, "callbackPath": { - "message": "Callback path" + "message": "Cesta zpětného volání" }, "signedOutCallbackPath": { - "message": "Signed out callback path" + "message": "Odhlášeno od cesty zpětného volání" }, "authority": { - "message": "Authority" + "message": "Autorita" }, "clientId": { - "message": "Client ID" + "message": "ID klienta" }, "clientSecret": { - "message": "Client secret" + "message": "Tajný klíč klienta" }, "metadataAddress": { - "message": "Metadata address" + "message": "Adresa metadat" }, "oidcRedirectBehavior": { - "message": "OIDC redirect behavior" + "message": "Chování přesměrování ODIC" }, "getClaimsFromUserInfoEndpoint": { - "message": "Get claims from user info endpoint" + "message": "Získat nároky z koncového bodu informací o uživateli" }, "additionalScopes": { - "message": "Custom scopes" + "message": "Vlastní rozsahy" }, "additionalUserIdClaimTypes": { - "message": "Custom user ID claim types" + "message": "Typy nároků vlastního ID uživatele" }, "additionalEmailClaimTypes": { - "message": "Email claim types" + "message": "Typy e-mailových nároků" }, "additionalNameClaimTypes": { - "message": "Custom name claim types" + "message": "Typy nároků vlastních jmen" }, "acrValues": { - "message": "Requested authentication context class reference values" + "message": "Požadované referenční hodnoty kontextové třídy ověřování" }, "expectedReturnAcrValue": { - "message": "Expected \"acr\" claim value in response" + "message": "Očekávaná hodnota nároku \"acr\" v odpovědi" }, "spEntityId": { - "message": "SP entity ID" + "message": "ID entity SP" }, "spMetadataUrl": { - "message": "SAML 2.0 metadata URL" + "message": "URL metadat SAML 2.0" }, "spAcsUrl": { - "message": "Assertion consumer service (ACS) URL" + "message": "URL ACS (Assertion Consumer Service)" }, "spNameIdFormat": { - "message": "Formát jména ID" + "message": "Formát ID názvu" }, "spOutboundSigningAlgorithm": { - "message": "Outbound signing algorithm" + "message": "Algoritmus odchozího podepisování" }, "spSigningBehavior": { - "message": "Signing behavior" + "message": "Chování podepisování" }, "spMinIncomingSigningAlgorithm": { - "message": "Minimum incoming signing algorithm" + "message": "Minimální příchozí podepisovací algoritmus" }, "spWantAssertionsSigned": { - "message": "Expect signed assertions" + "message": "Očekávaná podepsaná tvrzení" }, "spValidateCertificates": { - "message": "Validate certificates" + "message": "Ověřit certifikáty" }, "idpEntityId": { - "message": "ID subjektu" + "message": "ID entity" }, "idpBindingType": { - "message": "Binding type" + "message": "Typ vazby" }, "idpSingleSignOnServiceUrl": { - "message": "Single sign-on service URL" + "message": "URL pro jednotné přihlášení" }, "idpSingleLogoutServiceUrl": { - "message": "Single log-out service URL" + "message": "URL pro jednotné odhlášení" }, "idpX509PublicCert": { - "message": "X509 public certificate" + "message": "Veřejný certifikát X509" }, "idpOutboundSigningAlgorithm": { - "message": "Outbound signing algorithm" + "message": "Algoritmus odchozího podepisování" }, "idpAllowUnsolicitedAuthnResponse": { - "message": "Allow unsolicited authentication response" + "message": "Umožnit nevyžádanou ověřovací odpověď" }, "idpAllowOutboundLogoutRequests": { - "message": "Allow outbound logout requests" + "message": "Umožnit odchozí požadavky na odhlášení" }, "idpSignAuthenticationRequests": { - "message": "Sign authentication requests" + "message": "Požadavky na ověření podpisu" }, "ssoSettingsSaved": { - "message": "Single sign-on configuration saved" + "message": "Konfigurace jednotného přihlášení byla uložena" }, "sponsoredFamilies": { "message": "Free Bitwarden Families" }, "sponsoredFamiliesEligible": { - "message": "You and your family are eligible for Free Bitwarden Families. Redeem with your personal email to keep your data secure even when you are not at work." + "message": "Vy a Vaše rodina máte nárok na Free Bitwarden Families. Nárok můžete uplatnit Vaším osobním e-mailem, abyste zajistili bezpečnost Vašich dat, i když nejste v práci." }, "sponsoredFamiliesEligibleCard": { - "message": "Redeem your Free Bitwarden for Families plan today to keep your data secure even when you are not at work." + "message": "Uplatněte ještě dnes svůj plán Free Bitwarden for Families, aby byla Vaše data bezpečná, i když nejste v práci." }, "sponsoredFamiliesInclude": { - "message": "The Bitwarden for Families plan include" + "message": "Plán Bitwarden for Families obsahuje" }, "sponsoredFamiliesPremiumAccess": { - "message": "Premium access for up to 6 users" + "message": "Prémiový přístup až pro 6 uživatelů" }, "sponsoredFamiliesSharedCollections": { - "message": "Shared collections for Family secrets" + "message": "Sdílené kolekce pro tajné klíče rodiny" }, "badToken": { - "message": "The link is no longer valid. Please have the sponsor resend the offer." + "message": "Odkaz již není platný. Požádejte sponzora o opakované odeslání nabídky." }, "reclaimedFreePlan": { - "message": "Reclaimed free plan" + "message": "Bezplatný plán byl znovu nárokován" }, "redeem": { - "message": "Redeem" + "message": "Uplatnit" }, "sponsoredFamiliesSelectOffer": { - "message": "Select the organization you would like sponsored" + "message": "Vyberte organizaci, kterou chcete sponzorovat" }, "familiesSponsoringOrgSelect": { - "message": "Which Free Families offer would you like to redeem?" + "message": "Kterou nabídku Bitwarden Families chcete uplatnit?" }, "sponsoredFamiliesEmail": { - "message": "Enter your personal email to redeem Bitwarden Families" + "message": "Pro uplatnění Bitwarden Families zadejte Váš osobní e-mail" }, "sponsoredFamiliesLeaveCopy": { - "message": "If you remove an offer or are removed from the sponsoring organization, your Families sponsorship will expire at the next renewal date." + "message": "Pokud odeberete nabídku nebo budete odebráni ze sponzorské organizace, Vaše sponzorství rodiny vyprší k dalšímu datu obnovy." }, "acceptBitwardenFamiliesHelp": { - "message": "Accept offer for an existing organization or create a new Families organization." + "message": "Přijmout nabídku pro existující organizaci nebo vytvořit novou organizaci rodin." }, "setupSponsoredFamiliesLoginDesc": { - "message": "You've been offered a free Bitwarden Families plan organization. To continue, you need to log in to the account that received the offer." + "message": "Byla Vám nabídnuta bezplatná organizace plánu Bitwarden Families. Chcete-li pokračovat, musíte se přihlásit k účtu, který obdržel nabídku." }, "sponsoredFamiliesAcceptFailed": { - "message": "Unable to accept offer. Please resend the offer email from your Enterprise account and try again." + "message": "Nelze přijmout nabídku. Znovu odešlete e-mail s nabídkou z účtu Enterprise a zkuste to znovu." }, "sponsoredFamiliesAcceptFailedShort": { - "message": "Unable to accept offer. $DESCRIPTION$", + "message": "Nelze přijmout nabídku. $DESCRIPTION$", "placeholders": { "description": { "content": "$1", @@ -5098,19 +5098,19 @@ } }, "sponsoredFamiliesOffer": { - "message": "Accept Free Bitwarden Families" + "message": "Přijmout Free Bitwarden Families" }, "sponsoredFamiliesOfferRedeemed": { - "message": "Free Bitwarden Families offer successfully redeemed" + "message": "Nabídka Free Bitwarden Families byla úspěšně uplatněna" }, "redeemed": { - "message": "Redeemed" + "message": "Uplatněno" }, "redeemedAccount": { - "message": "Account redeemed" + "message": "Účet byl uplatněn" }, "revokeAccount": { - "message": "Revoke account $NAME$", + "message": "Odvolat účet $NAME$", "placeholders": { "name": { "content": "$1", @@ -5119,7 +5119,7 @@ } }, "resendEmailLabel": { - "message": "Resend sponsorship email to $NAME$ sponsorship", + "message": "Znovu poslat sponzorský e-mail pro sponzorství $NAME$", "placeholders": { "name": { "content": "$1", @@ -5128,61 +5128,61 @@ } }, "freeFamiliesPlan": { - "message": "Free Families plan" + "message": "Plán Free Families" }, "redeemNow": { - "message": "Redeem now" + "message": "Uplatnit nyní" }, "recipient": { - "message": "Recipient" + "message": "Příjemce" }, "removeSponsorship": { - "message": "Remove sponsorship" + "message": "Odebrat sponzorství" }, "removeSponsorshipConfirmation": { - "message": "After removing a sponsorship, you will be responsible for this subscription and related invoices. Are you sure you want to continue?" + "message": "Po odebrání sponzorství budete zodpovědni za toto předplatné a související faktury. Opravdu chcete pokračovat?" }, "sponsorshipCreated": { - "message": "Sponsorship created" + "message": "Sponzorství bylo vytvořeno" }, "emailSent": { - "message": "Email odeslán" + "message": "E-mail byl odeslán" }, "revokeSponsorshipConfirmation": { - "message": "After removing this account, the Families plan sponsorship will expire at the end of the billing period. You will not be able to redeem a new sponsorship offer until the existing one expires. Are you sure you want to continue?" + "message": "Po odebrání tohoto účtu vyprší sponzorování rodinného plánu na konci fakturační doby. Nebudete moci uplatnit novou nabídku sponzorování, dokud stávající neskončí. Opravdu chcete pokračovat?" }, "removeSponsorshipSuccess": { - "message": "Sponsorship removed" + "message": "Sponzorství bylo odebráno" }, "ssoKeyConnectorError": { - "message": "Key Connector error: make sure Key Connector is available and working correctly." + "message": "Chyba Key Connector: ujistěte se, že je Key Connector k dispozici a funguje správně." }, "keyConnectorUrl": { - "message": "Key Connector URL" + "message": "URL Key Connectoru" }, "sendVerificationCode": { - "message": "Send a verification code to your email" + "message": "Poslat ověřovací kód na Váš e-mail" }, "sendCode": { - "message": "Send code" + "message": "Poslat kód" }, "codeSent": { - "message": "Code sent" + "message": "Kód byl odeslán" }, "verificationCode": { "message": "Ověřovací kód" }, "confirmIdentity": { - "message": "Confirm your identity to continue." + "message": "Pro pokračování potvrďte svou identitu." }, "verificationCodeRequired": { - "message": "Verification code is required." + "message": "Je vyžadován ověřovací kód." }, "invalidVerificationCode": { - "message": "Invalid verification code" + "message": "Neplatný ověřovací kód" }, "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", + "message": "$ORGANIZATION$ používá SSO s vlastním serverem s klíči. Hlavní heslo pro členy této organizace již není vyžadováno.", "placeholders": { "organization": { "content": "$1", @@ -5191,37 +5191,37 @@ } }, "leaveOrganization": { - "message": "Leave organization" + "message": "Opustit organizaci" }, "removeMasterPassword": { - "message": "Remove master password" + "message": "Odebrat hlavní heslo" }, "removedMasterPassword": { - "message": "Master password removed" + "message": "Hlavní heslo bylo odebráno" }, "allowSso": { - "message": "Allow SSO authentication" + "message": "Povolit ověření přes SSO" }, "allowSsoDesc": { - "message": "Once set up, your configuration will be saved and members will be able to authenticate using their Identity Provider credentials." + "message": "Po nastavení bude Vaše konfigurace uložena a členové se budou moci ověřit pomocí jejich přihlašovacích údajů poskytovatele identity." }, "ssoPolicyHelpStart": { - "message": "Use the", + "message": "Použít", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Use the require single-sign-on authentication policy to require all members to log in with SSO.'" }, "ssoPolicyHelpLink": { - "message": "require single-sign-on authentication policy", + "message": "vyžadování zásad ověření jednotným přihlášením", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Use the require single-sign-on authentication policy to require all members to log in with SSO.'" }, "ssoPolicyHelpEnd": { - "message": "to require all members to log in with SSO.", + "message": "pro to, aby se všichni členové přihlašovali pomocí SSO.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Use the require single-sign-on authentication policy to require all members to log in with SSO.'" }, "memberDecryptionOption": { - "message": "Member decryption options" + "message": "Volby dešifrování členů" }, "memberDecryptionPassDesc": { - "message": "Once authenticated, members will decrypt vault data using their master passwords." + "message": "Po ověření budou členové dešifrovat data v trezoru pomocí jejich hlavních hesel." }, "keyConnector": { "message": "Key Connector" @@ -5239,124 +5239,124 @@ "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.'" }, "keyConnectorPolicyRestriction": { - "message": "\"Login with SSO and Key Connector Decryption\" is activated. This policy will only apply to owners and admins." + "message": "Je aktivní volba \"Přihlásit se s SSO a dešifrováním Key Connectorem\". Zásady se budou vztahovat jen na vlastníky a adminostrátory." }, "enabledSso": { - "message": "SSO turned on" + "message": "SSO je zapnuto" }, "disabledSso": { - "message": "SSO turned on" + "message": "SSO je vypnuto" }, "enabledKeyConnector": { - "message": "Key Connector activated" + "message": "Je aktivován Key Connector" }, "disabledKeyConnector": { - "message": "Key Connector deactivated" + "message": "Key Connector je deaktivován" }, "keyConnectorWarning": { - "message": "Once members begin using Key Connector, your organization cannot revert to master password decryption. Proceed only if you are comfortable deploying and managing a key server." + "message": "Jakmile členové začnou používat Key Connector, Vaše organizace se nemůže vrátit k dešifrování hlavního hesla. Pokračujte jen v případě, že bez problémů dokážete nasadit a spravovat server s klíči." }, "migratedKeyConnector": { - "message": "Migrated to Key Connector" + "message": "Migrováno do Key Connectoru" }, "paymentSponsored": { - "message": "Please provide a payment method to associate with the organization. Don't worry, we won't charge you anything unless you select additional features or your sponsorship expires. " + "message": "Zadejte metodu platby, která se připojí k organizaci. Nebudeme Vám nic účtovat, dokud nevyberete další funkce nebo dokud nevyprší Vaše sponzorství. " }, "orgCreatedSponsorshipInvalid": { - "message": "The sponsorship offer has expired. You may delete the organization you created to avoid a charge at the end of your 7 day trial. Otherwise you may close this prompt to keep the organization and assume billing responsibility." + "message": "Nabídka sponzorství vypršela. Vytvořenou organizaci můžete smazat, abyste se vyhnuli poplatku na konci 7denní zkušební doby. V opačném případě můžete tuto výzvu zavřít, abyste si organizaci ponechali a převzali odpovědnost za vyúčtování." }, "newFamiliesOrganization": { - "message": "New Families organization" + "message": "Nová organizace Families" }, "acceptOffer": { - "message": "Accept offer" + "message": "Přijmout Nabídku" }, "sponsoringOrg": { - "message": "Sponsoring organization" + "message": "Sponzorující organizace" }, "keyConnectorTest": { "message": "Test" }, "keyConnectorTestSuccess": { - "message": "Success! Key Connector reached." + "message": "Úspěch! Byl kontaktován Key Connector." }, "keyConnectorTestFail": { - "message": "Cannot reach Key Connector. Check URL." + "message": "Nelze kontaktovat Key Connector. Zkontrolujte URL." }, "sponsorshipTokenHasExpired": { - "message": "The sponsorship offer has expired." + "message": "Nabídka sponzorství již vypršela." }, "freeWithSponsorship": { - "message": "FREE with sponsorship" + "message": "ZDARMA se sponzorstvím" }, "viewBillingSyncToken": { - "message": "View billing sync token" + "message": "Zobrazit fakturační synchronizační token" }, "generateBillingSyncToken": { - "message": "Generate billing sync token" + "message": "Vygenerovat fakturační synchronizační token" }, "copyPasteBillingSync": { - "message": "Copy and paste this token into the billing sync settings of your self-hosted organization." + "message": "Zkopírujte a vložte tento token do nastavení fakturační synchronizace vlastní organizace." }, "billingSyncCanAccess": { - "message": "Your billing sync token can access and edit this organization's subscription settings." + "message": "Fakturační synchronizační token může přistupovat k nastavení předplatného této organizace a upravovat jej." }, "manageBillingSync": { - "message": "Manage billing sync" + "message": "Spravovat fakturační synchronizaci" }, "setUpBillingSync": { - "message": "Set up billing sync" + "message": "Nastavit fakturační synchronizaci" }, "generateToken": { - "message": "Generate token" + "message": "Vygenerovat token" }, "rotateToken": { - "message": "Rotate token" + "message": "Měnit token" }, "rotateBillingSyncTokenWarning": { - "message": "If you proceed, you will need to re-setup billing sync on your self-hosted server." + "message": "Pokud budete pokračovat, budete muset znovu nastavit fakturační synchronizaci na vlastním serveru." }, "rotateBillingSyncTokenTitle": { - "message": "Rotating the billing sync token will invalidate the previous token." + "message": "Měnění fakturačního synchronizačního tokenu zruší platnost předchozího tokenu." }, "selfHostingTitle": { - "message": "Self-hosting" + "message": "Vlastní hosting" }, "selfHostingEnterpriseOrganizationSectionCopy": { - "message": "To set-up your organization on your own server, you will need to upload your license file. To support Free Families plans and advanced billing capabilities for your self-hosted organization, you will need to set up billing sync." + "message": "Pro nastavení organizace na vlastním serveru musíte nahrát licenční soubor. Chcete-li podporovat plány Free Families a pokročilé možnosti fakturace pro Vaši organizaci na vlastním serveru, budete muset nastavit synchronizaci fakturace." }, "billingSyncApiKeyRotated": { - "message": "Token rotated" + "message": "Token byl vyměněn" }, "billingSyncDesc": { - "message": "Billing sync unlocks Families sponsorships and automatic license syncing on your server. After making updates in the Bitwarden cloud server, select Sync License to apply changes." + "message": "Synchronizace fakturace odemkne sponzorství Families a automatickou synchronizaci licencí na serveru. Po provedení aktualizací na cloudovém serveru Bitwardenu použijte pro použití změn funkci \"Synchronizovat licenci\"." }, "billingSyncKeyDesc": { - "message": "A billing sync token from your cloud organization's subscription settings is required to complete this form." + "message": "K vyplnění tohoto formuláře je vyžadován fakturační synchronizační token z nastavení předplatného Vaší cloudové organizace." }, "billingSyncKey": { - "message": "Billing sync token" + "message": "Fakturační synchronizační token" }, "active": { "message": "Aktivní" }, "inactive": { - "message": "Inactive" + "message": "Neaktivní" }, "sentAwaitingSync": { - "message": "Sent (awaiting sync)" + "message": "Odesláno (čeká na synchronizaci)" }, "sent": { - "message": "Sent" + "message": "Odesláno" }, "requestRemoved": { - "message": "Removed (awaiting sync)" + "message": "Odebráno (čeká na synchronizaci)" }, "requested": { - "message": "Requested" + "message": "Vyžádáno" }, "formErrorSummaryPlural": { - "message": "$COUNT$ fields above need your attention.", + "message": "$COUNT$ polí výše vyžadují Vaši pozornost.", "placeholders": { "count": { "content": "$1", @@ -5365,10 +5365,10 @@ } }, "formErrorSummarySingle": { - "message": "1 field above needs your attention." + "message": "1 pole výše vyžaduje Vaši pozornost." }, "fieldRequiredError": { - "message": "$FIELDNAME$ is required.", + "message": "$FIELDNAME$ je vyžadováno.", "placeholders": { "fieldname": { "content": "$1", @@ -5377,10 +5377,10 @@ } }, "required": { - "message": "required" + "message": "vyžadováno" }, "characterMaximum": { - "message": "$MAX$ character maximum", + "message": "Maximálně $MAX$ znaků", "placeholders": { "max": { "content": "$1", @@ -5389,28 +5389,28 @@ } }, "idpSingleSignOnServiceUrlRequired": { - "message": "Required if Entity ID is not a URL." + "message": "Vyžadováno, pokud ID entity není URL." }, "openIdOptionalCustomizations": { - "message": "Optional customizations" + "message": "Volitelné úpravy" }, "openIdAuthorityRequired": { - "message": "Required if Authority is not valid." + "message": "Vyžadováno, pokud není autorita platná." }, "separateMultipleWithComma": { - "message": "Separate multiple with a comma." + "message": "Další oddělte čárkami." }, "sessionTimeout": { - "message": "Your session has timed out. Please go back and try logging in again." + "message": "Vypršel časový limit relace. Vraťte se zpět a zkuste se znovu přihlásit." }, "exportingPersonalVaultTitle": { - "message": "Exporting individual vault" + "message": "Exportování osobního trezoru" }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "Exportování trezoru organizace" }, "exportingPersonalVaultDescription": { - "message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated password history or attachments.", + "message": "Budou exportovány jen osobní položky trezoru spojené s $EMAIL$. Položky trezoru organizace nebudou zahrnuty. Budou exportovány jen informace o položkách trezoru a nebudou zahrnuty související historie hesel ani přílohy.", "placeholders": { "email": { "content": "$1", @@ -5419,7 +5419,7 @@ } }, "exportingOrganizationVaultDescription": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Individual vault items and items from other organizations will not be included.", + "message": "Exportován bude jen trezor organizace přidružený k položce $ORGANIZATION$. Osobní položky trezoru a položky z jiných organizací nebudou zahrnuty.", "placeholders": { "organization": { "content": "$1", @@ -5428,28 +5428,28 @@ } }, "accessDenied": { - "message": "Access denied. You do not have permission to view this page." + "message": "Přístup byl odepřen. Nemáte oprávnění k zobrazení této stránky." }, "masterPassword": { - "message": "Master password" + "message": "Hlavní heslo" }, "security": { - "message": "Security" + "message": "Zabezpečení" }, "keys": { - "message": "Keys" + "message": "Klíče" }, "billingHistory": { - "message": "Billing history" + "message": "Historie fakturace" }, "backToReports": { - "message": "Back to reports" + "message": "Zpět do hlášení" }, "organizationPicker": { - "message": "Organization picker" + "message": "Výběr organizace" }, "currentOrganization": { - "message": "Current organization", + "message": "Aktuální organizace", "description": "This is used by screen readers to indicate the organization that is currently being shown to the user." }, "accountLoggedInAsName": { @@ -5465,7 +5465,7 @@ "message": "Nastavení účtu" }, "generator": { - "message": "Generator" + "message": "Generátor" }, "whatWouldYouLikeToGenerate": { "message": "Co chcete vygenerovat?" @@ -5474,45 +5474,45 @@ "message": "Typ hesla" }, "regenerateUsername": { - "message": "Regenerate username" + "message": "Znovu vygenerovat uživatelské jméno" }, "generateUsername": { - "message": "Generate username" + "message": "Vygenerovat uživatelské jméno" }, "usernameType": { - "message": "Username type" + "message": "Typ uživatelského jména" }, "plusAddressedEmail": { - "message": "Plus addressed email", + "message": "E-mailová adresa s plusem", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "Use your email provider's sub-addressing capabilities." + "message": "Použijte funkce podadres Vašeho poskytovatele e-mailu." }, "catchallEmail": { - "message": "Catch-all email" + "message": "E-mail pro doménový koš" }, "catchallEmailDesc": { - "message": "Use your domain's configured catch-all inbox." + "message": "Použijte nakonfigurovanou univerzální schránku své domény." }, "random": { - "message": "Random", + "message": "Náhodně", "description": "Generates domain-based username using random letters" }, "randomWord": { - "message": "Random word" + "message": "Náhodné slovo" }, "service": { - "message": "Service" + "message": "Služba" }, "unknownCipher": { - "message": "Unknown item, you may need to request permission to access this item." + "message": "Neznámá položka, možná budete muset požádat o oprávnění pro přístup k této položce." }, "cannotSponsorSelf": { - "message": "You cannot redeem for the active account. Enter a different email." + "message": "Nemůžete uplatnit pro aktivní účet. Zadejte jiný e-mail." }, "revokeWhenExpired": { - "message": "Expires $DATE$", + "message": "Vyprší $DATE$", "placeholders": { "date": { "content": "$1", @@ -5521,7 +5521,7 @@ } }, "awaitingSyncSingular": { - "message": "Token rotated $DAYS$ day ago. Update the billing sync token in your self-hosted organization settings.", + "message": "Token se změnil před $DAYS$ dnem. Aktualizujte fakturační synchronizační token v nastavení vlastního hostingu Vaší organizace.", "placeholders": { "days": { "content": "$1", @@ -5530,7 +5530,7 @@ } }, "awaitingSyncPlural": { - "message": "Token rotated $DAYS$ days ago. Update the billing sync token in your self-hosted organization settings.", + "message": "Token se změnil před $DAYS$ dny. Aktualizujte fakturační synchronizační token v nastavení vlastního hostingu Vaší organizace.", "placeholders": { "days": { "content": "$1", @@ -5539,14 +5539,14 @@ } }, "lastSync": { - "message": "Last sync", + "message": "Poslední synchronizace", "description": "Used as a prefix to indicate the last time a sync occured. Example \"Last sync 1968-11-16 00:00:00\"" }, "sponsorshipsSynced": { - "message": "Self-hosted sponsorships synced." + "message": "Sponzoringy na vlastním hostingu byly synchronizovány." }, "billingManagedByProvider": { - "message": "Managed by $PROVIDER$", + "message": "Spravováno poskytovatelem $PROVIDER$", "placeholders": { "provider": { "content": "$1", @@ -5555,36 +5555,36 @@ } }, "billingContactProviderForAssistance": { - "message": "Please reach out to them for further assistance", + "message": "Pro další pomoc kontaktujte tohoto poskytovatele", "description": "This text is displayed if an organization's billing is managed by a Provider. It tells the user to contact the Provider for assistance." }, "forwardedEmail": { - "message": "Forwarded email alias" + "message": "Alias přeposílaného e-mailu" }, "forwardedEmailDesc": { - "message": "Generate an email alias with an external forwarding service." + "message": "Vygeneruje alias e-mailu pomocí externí přeposílací služby." }, "hostname": { - "message": "Hostname", + "message": "Název hostitele", "description": "Part of a URL." }, "apiAccessToken": { - "message": "API access token" + "message": "Přístupový token API" }, "deviceVerification": { - "message": "Device verification" + "message": "Ověřování zařízení" }, "enableDeviceVerification": { - "message": "Turn on device verification" + "message": "Zapnout ověřování zařízení" }, "deviceVerificationDesc": { - "message": "Verification codes are sent to your email address when logging in from an unrecognized device" + "message": "Při přihlášení z neznámého zařízení budou na Vaši e-mailovou adresu odeslány ověřovací kódy." }, "updatedDeviceVerification": { - "message": "Updated device verification" + "message": "Ověření aktualizovaného zařízení" }, "areYouSureYouWantToEnableDeviceVerificationTheVerificationCodeEmailsWillArriveAtX": { - "message": "Are you sure you want to turn on device verification? The verification code emails will arrive at: $EMAIL$", + "message": "Opravdu chcete zapnout ověřování zařízení? Ověřovací kódy budou zaslány na e-mail $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -5593,67 +5593,67 @@ } }, "premiumSubcriptionRequired": { - "message": "Premium subscription required" + "message": "Je vyžadováno předplatné Premium" }, "scim": { "message": "Poskytování SCIM", "description": "The text, 'SCIM', is an acronymn and should not be translated." }, "scimDescription": { - "message": "Automaticky zajišťuje uživatelům a skupinám vašeho preferovaného poskytovatele identity prostřednictvím SCIM poskytování", + "message": "Automatické zajišťování uživatelů a skupin u preferovaného poskytovatele identit prostřednictvím zajišťování SCIM.", "description": "the text, 'SCIM', is an acronymn and should not be translated." }, "scimEnabledCheckboxDesc": { - "message": "Aktivovat SCIM", + "message": "Povolit SCIM", "description": "the text, 'SCIM', is an acronymn and should not be translated." }, "scimEnabledCheckboxDescHelpText": { - "message": "Nastavte svého preferovaného poskytovatele identity nastavením URL a SCIM API klíče", + "message": "Nastavte svého preferovaného poskytovatele identity nastavením URL a klíče SCIM API", "description": "the text, 'SCIM', is an acronymn and should not be translated." }, "scimApiKeyHelperText": { - "message": "Tento klíč API má přístup ke správě uživatelů ve vaší organizaci. Měl by být zachován v tajnosti." + "message": "Tento klíč API má přístup ke správě uživatelů ve Vaší organizaci. Měl by být zachován v tajnosti." }, "copyScimKey": { - "message": "Zkopírujte SCIM API klíč do schránky", + "message": "Kopírovat klíč SCIM API do schránky", "description": "the text, 'SCIM' and 'API', are acronymns and should not be translated." }, "rotateScimKey": { - "message": "Vyměňte SCIM API klíč", + "message": "Měnit klíč SCIM API", "description": "the text, 'SCIM' and 'API', are acronymns and should not be translated." }, "rotateScimKeyWarning": { - "message": "Opravdu chcete změnit SCIM API klíč? Aktuální klíč již nebude fungovat pro žádné existující integrace.", + "message": "Opravdu chcete měnit klíč SCIM API? Aktuální klíč již nebude fungovat pro žádné existující integrace.", "description": "the text, 'SCIM' and 'API', are acronymns and should not be translated." }, "rotateKey": { "message": "Změnit klíč" }, "scimApiKey": { - "message": "SCIM API klíč", + "message": "Klíč SCIM API", "description": "the text, 'SCIM' and 'API', are acronymns and should not be translated." }, "copyScimUrl": { - "message": "Zkopírujte URL adresu SCIM koncového bodu do schránky", + "message": "Kopírovat URL koncového bodu SCIM do schránky", "description": "the text, 'SCIM' and 'URL', are acronymns and should not be translated." }, "scimUrl": { - "message": "SCIM URL", + "message": "URL SCIM", "description": "the text, 'SCIM' and 'URL', are acronymns and should not be translated." }, "scimApiKeyRotated": { - "message": "SCIM API klíč byl úspěšně změněn", + "message": "Klíč SCIM API byl úspěšně změněn", "description": "the text, 'SCIM' and 'API', are acronymns and should not be translated." }, "scimSettingsSaved": { - "message": "Nastavení SCIM bylo úspěšně uloženo", + "message": "Nastavení SCIM bylo uloženo", "description": "the text, 'SCIM', is an acronymn and should not be translated." }, "inputRequired": { - "message": "Položka nesmí být prázdná." + "message": "Je vyžadován vstup." }, "inputEmail": { - "message": "Neplatná e-mailová adresa." + "message": "Vstup není e-mailová adresa." }, "inputMinLength": { "message": "Vstup musí mít alespoň $COUNT$ znaků.", @@ -5665,7 +5665,7 @@ } }, "inputMaxLength": { - "message": "Input must not exceed $COUNT$ characters in length.", + "message": "Vstup nesmí být delší než $COUNT$ znaků.", "placeholders": { "count": { "content": "$1", @@ -5674,7 +5674,7 @@ } }, "inputForbiddenCharacters": { - "message": "The following characters are not allowed: $CHARACTERS$", + "message": "Následující znaky nejsou povoleny: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -5701,10 +5701,10 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "1 nebo více e-mailů jsou neplatné" }, "tooManyEmails": { - "message": "You can only submit up to $COUNT$ emails at a time", + "message": "Najednou můžete odeslat jen $COUNT$ e-mailů", "placeholders": { "count": { "content": "$1", @@ -5713,7 +5713,7 @@ } }, "fieldsNeedAttention": { - "message": "$COUNT$ výše uvedených polí vyžaduje vaši pozornost.", + "message": "$COUNT$ polí výše vyžaduje Vaši pozornost.", "placeholders": { "count": { "content": "$1", @@ -5731,225 +5731,225 @@ "message": "Členové" }, "reporting": { - "message": "Reporting" + "message": "Hlášení" }, "numberOfUsers": { - "message": "Number of users" + "message": "Počet uživatelů" }, "loggingInAs": { - "message": "Logging in as" + "message": "Přihlašování jako" }, "notYou": { - "message": "Not you?" + "message": "Nejste to Vy?" }, "pickAnAvatarColor": { - "message": "Pick an avatar color" + "message": "Zvolte barvu avatara" }, "customizeAvatar": { - "message": "Customize avatar" + "message": "Přizpůsobit avatara" }, "avatarUpdated": { - "message": "Avatar updated" + "message": "Avatar byl aktualizován" }, "brightBlue": { - "message": "Bright Blue" + "message": "Světle modrá" }, "green": { - "message": "Green" + "message": "Zelená" }, "orange": { - "message": "Orange" + "message": "Oranžová" }, "lavender": { - "message": "Lavender" + "message": "Levandulová" }, "yellow": { - "message": "Yellow" + "message": "Žlutá" }, "indigo": { - "message": "Indigo" + "message": "Tmavě modrá" }, "teal": { "message": "Teal" }, "salmon": { - "message": "Salmon" + "message": "Lososová" }, "pink": { - "message": "Pink" + "message": "Růžová" }, "customColor": { - "message": "Custom Color" + "message": "Vlastní barva" }, "selectPlaceholder": { - "message": "-- Select --" + "message": "-- Vybrat --" }, "multiSelectPlaceholder": { - "message": "-- Type to filter --" + "message": "-- Pište pro filtrování --" }, "multiSelectLoading": { - "message": "Retrieving options..." + "message": "Načítání voleb..." }, "multiSelectNotFound": { - "message": "No items found" + "message": "Nebyly nalezeny žádné položky" }, "multiSelectClearAll": { - "message": "Clear all" + "message": "Vymazat vše" }, "toggleCharacterCount": { - "message": "Toggle character count", + "message": "Zobrazit počet znaků", "description": "'Character count' describes a feature that displays a number next to each character of the password." }, "passwordCharacterCount": { - "message": "Password character count", + "message": "Počet znaků hesla", "description": "'Character count' describes a feature that displays a number next to each character of the password." }, "hide": { - "message": "Hide" + "message": "Skrýt" }, "projects": { - "message": "Projects", + "message": "Projekty", "description": "Description for the Projects field." }, "lastEdited": { - "message": "Last edited", + "message": "Naposledy upraveno", "description": "The label for the date and time when a item was last edited." }, "editSecret": { - "message": "Edit secret", + "message": "Upravit tajný klíč", "description": "Action to modify an existing secret." }, "addSecret": { - "message": "Add secret", + "message": "Přidat tajný klíč", "description": "Action to create a new secret." }, "copySecretName": { - "message": "Copy secret name", + "message": "Kopírovat název tajného klíče", "description": "Action to copy the name of a secret to the system's clipboard." }, "copySecretValue": { - "message": "Copy secret value", + "message": "Kopírovat hodnotu tajného klíče", "description": "Action to copy the value of a secret to the system's clipboard." }, "deleteSecret": { - "message": "Delete secret", + "message": "Smazat tajný klíč", "description": "Action to delete a single secret from the system." }, "deleteSecrets": { - "message": "Delete secrets", + "message": "Smazat tajné klíče", "description": "The action to delete multiple secrets from the system." }, "hardDeleteSecret": { - "message": "Permanently delete secret" + "message": "Trvale smazat tajný klíč" }, "hardDeleteSecrets": { - "message": "Permanently delete secrets" + "message": "Trvale smazat tajné klíče" }, "secretProjectAssociationDescription": { - "message": "Select projects that the secret will be associated with. Only organization users with access to these projects will be able to see the secret.", + "message": "Vyberte projekty, se kterými bude spojen tajný klíč. Tajný klíč budou moci vidět jen uživatelé organizace s přístupem k těmto projektům.", "description": "A prompt explaining how secrets can be associated with projects." }, "selectProjects": { - "message": "Select projects", + "message": "Vybrat projekty", "description": "A label for a type-to-filter input field to choose projects." }, "searchProjects": { - "message": "Search projects", + "message": "Prohledat projekty", "description": "Label for the search bar used to search projects." }, "project": { - "message": "Project", + "message": "Projekt", "description": "Similar to collections, projects can be used to group secrets." }, "editProject": { - "message": "Edit project", + "message": "Upravit projekt", "description": "The action to modify an existing project." }, "viewProject": { - "message": "View project", + "message": "Zobrazit projekt", "description": "The action to view details of a project." }, "deleteProject": { - "message": "Delete project", + "message": "Smazat projekt", "description": "The action to delete a project from the system." }, "deleteProjects": { - "message": "Delete projects", + "message": "Smazat projekty", "description": "The action to delete multiple projects from the system." }, "secret": { - "message": "Secret", + "message": "Tajný klíč", "description": "Label for a secret (key/value pair)" }, "serviceAccount": { - "message": "Service account", + "message": "Účet služby", "description": "A machine user which can be used to automate processes and access secrets in the system." }, "serviceAccounts": { - "message": "Service accounts", + "message": "Účty služeb", "description": "The title for the section that deals with service accounts." }, "secrets": { - "message": "Secrets", + "message": "Tajné klíče", "description": "The title for the section of the application that deals with secrets." }, "nameValuePair": { - "message": "Name/Value pair", + "message": "Dvojice Název/Hodnota", "description": "Title for a name/ value pair. Secrets typically consist of a name and value pair." }, "secretEdited": { - "message": "Secret edited", + "message": "Tajný klíč byl upraven", "description": "Notification for the successful editing of a secret." }, "secretCreated": { - "message": "Secret created", + "message": "Tajný klíč byl vytvořen", "description": "Notification for the successful creation of a secret." }, "newSecret": { - "message": "New secret", + "message": "Nový tajný klíč", "description": "Title for creating a new secret." }, "newServiceAccount": { - "message": "New service account", + "message": "Nový účet služby", "description": "Title for creating a new service account." }, "secretsNoItemsTitle": { - "message": "No secrets to show", + "message": "Žádné tajné klíče k zobrazení", "description": "Empty state to indicate that there are no secrets to display." }, "secretsNoItemsMessage": { - "message": "To get started, add a new secret or import secrets.", + "message": "Chcete-li začít, přidejte nový tajný klíč nebo importujte tajný klíč.", "description": "Message to encourage the user to start adding secrets." }, "secretsTrashNoItemsMessage": { - "message": "There are no secrets in the trash." + "message": "V koši nejsou žádné tajné klíče." }, "serviceAccountsNoItemsMessage": { - "message": "Create a new service account to get started automating secret access.", + "message": "Abyste mohli začít automatizovat přístup k tajnému kliči, vytvořte nový účet služby.", "description": "Message to encourage the user to start creating service accounts." }, "serviceAccountsNoItemsTitle": { - "message": "Nothing to show yet", + "message": "Nyní není nic k zobrazení", "description": "Title to indicate that there are no service accounts to display." }, "searchSecrets": { - "message": "Search secrets", + "message": "Prohledat tajné klíče", "description": "Placeholder text for searching secrets." }, "deleteServiceAccounts": { - "message": "Delete service accounts", + "message": "Smazat účty služby", "description": "Title for the action to delete one or multiple service accounts." }, "deleteServiceAccount": { - "message": "Delete service account", + "message": "Smazat účet služby", "description": "Title for the action to delete a single service account." }, "viewServiceAccount": { - "message": "View service account", + "message": "Zobrazit účet služby", "description": "Action to view the details of a service account." }, "deleteServiceAccountDialogMessage": { - "message": "Deleting service account $SERVICE_ACCOUNT$ is permanent and irreversible.", + "message": "Smazání účtu služby $SERVICE_ACCOUNT$ je trvalé a nevratné.", "placeholders": { "service_account": { "content": "$1", @@ -5958,10 +5958,10 @@ } }, "deleteServiceAccountsDialogMessage": { - "message": "Deleting service accounts is permanent and irreversible." + "message": "Smazání účtů služby je trvalé a nevratné." }, "deleteServiceAccountsConfirmMessage": { - "message": "Delete $COUNT$ service accounts", + "message": "Smazat $COUNT$ účtů služby", "placeholders": { "count": { "content": "$1", @@ -5970,98 +5970,98 @@ } }, "deleteServiceAccountToast": { - "message": "Service account deleted" + "message": "Účet služby byl smazán" }, "deleteServiceAccountsToast": { - "message": "Service accounts deleted" + "message": "Účet služeb byly smazány" }, "searchServiceAccounts": { - "message": "Search service accounts", + "message": "Prohledat účty služeb", "description": "Placeholder text for searching service accounts." }, "editServiceAccount": { - "message": "Edit service account", + "message": "Upravit účet služby", "description": "Title for editing a service account." }, "addProject": { - "message": "Add project", + "message": "Přidat projekt", "description": "Title for creating a new project." }, "projectEdited": { - "message": "Project edited", + "message": "Projekt byl upraven", "description": "Notification for the successful editing of a project." }, "projectSaved": { - "message": "Project saved", + "message": "Projekt byl uložen", "description": "Notification for the successful saving of a project." }, "projectCreated": { - "message": "Project created", + "message": "Projekt byl vytvořen", "description": "Notification for the successful creation of a project." }, "projectName": { - "message": "Project name", + "message": "Název projektu", "description": "Label for entering the name of a project." }, "newProject": { - "message": "New project", + "message": "Nový projekt", "description": "Title for creating a new project." }, "softDeleteSecretWarning": { - "message": "Deleting secrets can affect existing integrations.", + "message": "Smazání tajných klíčů může ovlivnit existující integrace.", "description": "Warns that deleting secrets can have consequences on integrations" }, "softDeletesSuccessToast": { - "message": "Secrets sent to trash", + "message": "Tajné klíče byly přesunuty do koše", "description": "Notifies that the selected secrets have been moved to the trash" }, "hardDeleteSecretConfirmation": { - "message": "Are you sure you want to permanently delete this secret?" + "message": "Opravdu chcete tento tajný klíč trvale smazat?" }, "hardDeleteSecretsConfirmation": { - "message": "Are you sure you want to permanently delete these secrets?" + "message": "Opravdu chcete tyto tajné klíče trvale smazat?" }, "hardDeletesSuccessToast": { - "message": "Secrets permanently deleted" + "message": "Tajné klíče byly trvale smazány" }, "smAccess": { - "message": "Access", + "message": "Přístup", "description": "Title indicating what permissions a service account has" }, "projectCommaSecret": { - "message": "Project, Secret", + "message": "Projekt, Tajný klíč", "description": "" }, "serviceAccountName": { - "message": "Service account name", + "message": "Název účtu služby", "description": "Label for the name of a service account" }, "serviceAccountCreated": { - "message": "Service account created", + "message": "Účet služby byl vytvořen", "description": "Notifies that a new service account has been created" }, "serviceAccountUpdated": { - "message": "Service account updated", + "message": "Účet služby byl aktualizován", "description": "Notifies that a service account has been updated" }, "newSaSelectAccess": { - "message": "Type or select projects or secrets", + "message": "Napište nebo vyberte projekty nebo tajné klíče", "description": "Instructions for selecting projects or secrets for a new service account" }, "newSaTypeToFilter": { - "message": "Type to filter", + "message": "Pište pro filtrování", "description": "Instructions for filtering a list of projects or secrets" }, "deleteProjectsToast": { - "message": "Projects deleted", + "message": "Projekty byly smazány", "description": "Notifies that the selected projects have been deleted" }, "deleteProjectToast": { - "message": "Project deleted", + "message": "Projekty byly smazány", "description": "Notifies that a project has been deleted" }, "deleteProjectDialogMessage": { - "message": "Deleting project $PROJECT$ is permanent and irreversible.", + "message": "Smazání projektu $PROJECT$ je trvalé a nevratné.", "description": "Informs users that projects are hard deleted and not sent to trash", "placeholders": { "project": { @@ -6071,7 +6071,7 @@ } }, "deleteProjectInputLabel": { - "message": "Type \"$CONFIRM$\" to continue", + "message": "Pro pokračování napište \"$CONFIRM$\"", "description": "Users are prompted to type 'confirm' to delete a project", "placeholders": { "confirm": { @@ -6081,7 +6081,7 @@ } }, "deleteProjectConfirmMessage": { - "message": "Delete $PROJECT$", + "message": "Smazat $PROJECT$", "description": "Confirmation prompt to delete a specific project, where '$PROJECT$' is a placeholder for the name of the project.", "placeholders": { "project": { @@ -6091,7 +6091,7 @@ } }, "deleteProjectsConfirmMessage": { - "message": "Delete $COUNT$ Projects", + "message": "Smazat $COUNT$ projektů", "description": "Confirmation prompt to delete multiple projects, where '$COUNT$' is a placeholder for the number of projects to be deleted.", "placeholders": { "count": { @@ -6101,34 +6101,34 @@ } }, "deleteProjectsDialogMessage": { - "message": "Deleting projects is permanent and irreversible.", + "message": "Smazání projektů je trvalé a nevratné.", "description": "This message is displayed in a dialog box as a warning before proceeding with project deletion." }, "projectsNoItemsTitle": { - "message": "No projects to display", + "message": "Žádné projekty k zobrazení", "description": "Empty state to be displayed when there are no projects to display in the list." }, "projectsNoItemsMessage": { - "message": "Add a new project to get started organizing secrets.", + "message": "Chcete-li začít s organizováním tajných klíčů, přidejte nový projekt.", "description": "Message to be displayed when there are no projects to display in the list." }, "smConfirmationRequired": { - "message": "Confirmation required", + "message": "Je vyžadováno potvrzení", "description": "Indicates that user confirmation is required for an action to proceed." }, "bulkDeleteProjectsErrorMessage": { - "message": "The following projects could not be deleted:", + "message": "Následující projekty nemohou být smazány:", "description": "Message to be displayed when there is an error during bulk project deletion." }, "softDeleteSuccessToast": { - "message": "Secret sent to trash", + "message": "Tajný klíč byl přesunut do koše", "description": "Notification to be displayed when a secret is successfully sent to the trash." }, "hardDeleteSuccessToast": { - "message": "Secret permanently deleted" + "message": "Tajný klíč byl trvale smazán" }, "accessTokens": { - "message": "Access tokens", + "message": "Přístupové tokeny", "description": "Title for the section displaying access tokens." }, "newAccessToken": { @@ -6136,88 +6136,88 @@ "description": "Button label for creating a new access token." }, "expires": { - "message": "Expires", + "message": "Vyprší", "description": "Label for the expiration date of an access token." }, "canRead": { - "message": "Can read", + "message": "Jen ke čtení", "description": "Label for the access level of an access token (Read only)." }, "accessTokensNoItemsTitle": { - "message": "No access tokens to show", + "message": "Žádné přístupové tokeny k zobrazení", "description": "Title to be displayed when there are no access tokens to display in the list." }, "accessTokensNoItemsDesc": { - "message": "To get started, create an access token", + "message": "Chcete-li začít, vytvořte přístupový token", "description": "Message to be displayed when there are no access tokens to display in the list." }, "downloadAccessToken": { - "message": "Download or copy before closing.", + "message": "Před zavřením přístupového tokenu si jej stáhněte nebo zkopírujte.", "description": "Message to be displayed before closing an access token, reminding the user to download or copy it." }, "expiresOnAccessToken": { - "message": "Expires on:", + "message": "Platnost končí:", "description": "Label for the expiration date of an access token." }, "accessTokenCallOutTitle": { - "message": "Access tokens are not stored and cannot be retrieved", + "message": "Přístupové tokeny nejsou uloženy a nelze je znovu získat", "description": "Notification to inform the user that access tokens are only displayed once and cannot be retrieved again." }, "copyToken": { - "message": "Copy token", + "message": "Kopírovat token", "description": "Copies the generated access token to the user's clipboard." }, "accessToken": { - "message": "Access token", + "message": "Přístupový token", "description": "A unique string that gives a client application (eg. CLI) access to a secret or set of secrets." }, "accessTokenExpirationRequired": { - "message": "Expiration date required", + "message": "Je vyžadováno datum expirace", "description": "Error message indicating that an expiration date for the access token must be set." }, "accessTokenCreatedAndCopied": { - "message": "Access token created and copied to clipboard", + "message": "Přístupový token byl vytvořen a zkopírován do schránky", "description": "Notification to inform the user that the access token has been created and copied to the clipboard." }, "accessTokenPermissionsBetaNotification": { - "message": "Permissions management is unavailable for beta.", + "message": "Správa oprávnění není k dispozici pro beta.", "description": "Notification to inform the user that the feature for managing access token permissions is not available in the beta version." }, "revokeAccessToken": { - "message": "Revoke access token", + "message": "Odvolat přístupový token", "description": "Invalidates / cancels an access token and as such removes access to secrets for the client application." }, "revokeAccessTokens": { - "message": "Revoke access tokens" + "message": "Odvolat přístupové tokeny" }, "revokeAccessTokenDesc": { - "message": "Revoking access tokens is permanent and irreversible." + "message": "Odvolání přístupových tokenů je trvalé a nevratné." }, "accessTokenRevoked": { - "message": "Access tokens revoked", + "message": "Přístupové tokeny byly odvolány", "description": "Toast message after deleting one or multiple access tokens." }, "noAccessTokenSelected": { - "message": "Nebyl vybrán žádný přístupový token pro zrušení", + "message": "Nebyl vybrán žádný přístupový token pro odvolání", "description": "Toast error message after trying to delete access tokens but not selecting any access tokens." }, "submenu": { - "message": "Submenu" + "message": "Podmenu" }, "from": { - "message": "From" + "message": "Od" }, "to": { - "message": "To" + "message": "Do" }, "member": { "message": "Člen" }, "update": { - "message": "Update" + "message": "Aktualizovat" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ $QUANTITY$ dalších", "placeholders": { "quantity": { "content": "$1", @@ -6226,127 +6226,127 @@ } }, "groupInfo": { - "message": "Group info" + "message": "Informace o skupině" }, "editGroupMembersDesc": { - "message": "Grant members access to the group's assigned collections." + "message": "Udělí členům přístup k přiřazeným kolekcím skupiny." }, "editGroupCollectionsDesc": { - "message": "Grant access to collections by adding them to this group." + "message": "Udělí členům přístup ke kolekcím přidáním do této skupiny." }, "accessAllCollectionsDesc": { - "message": "Grant access to all current and future collections." + "message": "Udělí přístup ke všem aktuálním i budoucím kolekcím." }, "accessAllCollectionsHelp": { - "message": "If checked, this will replace all other collection permissions." + "message": "Pokud je zaškrtnuto, nahradí to všechna ostatní oprávnění ke kolekcím." }, "selectMembers": { - "message": "Select members" + "message": "Vybrat členy" }, "selectCollections": { - "message": "Select collections" + "message": "Vybrat kolekce" }, "role": { "message": "Role" }, "removeMember": { - "message": "Remove member" + "message": "Odebrat člena" }, "collection": { - "message": "Collection" + "message": "Kolekce" }, "noCollection": { - "message": "No collection" + "message": "Žádná kolekce" }, "canView": { - "message": "Can view" + "message": "Může zobrazit" }, "canViewExceptPass": { - "message": "Can view, except passwords" + "message": "Může zobrazit kromě hesel" }, "canEdit": { - "message": "Can edit" + "message": "Může upravovat" }, "canEditExceptPass": { - "message": "Can edit, except passwords" + "message": "Může upravovat kromě hesel" }, "noCollectionsAdded": { - "message": "No collections added" + "message": "Nebyly přidány žádné kolekce" }, "noMembersAdded": { - "message": "No members added" + "message": "Nebyli přidáni žádní členové" }, "noGroupsAdded": { - "message": "No groups added" + "message": "Nebyly přidány žádné skupiny" }, "group": { - "message": "Group" + "message": "Skupina" }, "groupAccessAll": { - "message": "This group can access and modify all items." + "message": "Tato skupina může vidět a upravovat vše." }, "memberAccessAll": { - "message": "This member can access and modify all items." + "message": "Tento uživatel může vidět a upravovat vše." }, "domainVerification": { - "message": "Domain verification" + "message": "Ověření domény" }, "newDomain": { - "message": "New domain" + "message": "Nová doména" }, "noDomains": { - "message": "No domains" + "message": "Žádné domény" }, "noDomainsSubText": { - "message": "Connecting a domain allows members to skip the SSO identifier field during Login with SSO." + "message": "Připojení domény umožňuje členům přeskočit pole identifikátoru SSO během přihlašování pomocí SSO." }, "verifyDomain": { - "message": "Verify domain" + "message": "Ověřit doménu" }, "reverifyDomain": { - "message": "Reverify domain" + "message": "Znovu ověřit doménu" }, "copyDnsTxtRecord": { - "message": "Copy DNS TXT record" + "message": "Kopírovat TXT záznam DNS" }, "dnsTxtRecord": { - "message": "DNS TXT record" + "message": "TXT záznam DNS" }, "dnsTxtRecordInputHint": { - "message": "Copy and paste the TXT record into your DNS Provider." + "message": "Zkopírujte a vložte TXT záznam do poskytovatele DNS." }, "domainNameInputHint": { - "message": "Example: mydomain.com. Subdomains require separate entries to be verified." + "message": "Příklad: mydomain.com. Poddomény vyžadují samostatné záznamy, které je třeba ověřit." }, "automaticDomainVerification": { - "message": "Automatic Domain Verification" + "message": "Automatické ověření domény" }, "automaticDomainVerificationProcess": { - "message": "Bitwarden will attempt to verify the domain 3 times during the first 72 hours. If the domain can’t be verified, check the DNS record in your host and manually verify. The domain will be removed from your organization in 7 days if it is not verified" + "message": "Bitwarden se pokusí ověřit doménu třikrát během prvních 72 hodin. Pokud doménu nelze ověřit, zkontrolujte záznam DNS v hostitelském počítači a ověřte ji ručně. Pokud se doména nepodaří ověřit, bude z Vaší organizace odebrána do 7 dnů." }, "invalidDomainNameMessage": { - "message": "Input is not a valid format. Format: mydomain.com. Subdomains require separate entries to be verified." + "message": "Vstup není platný formát. Příklad: mydomain.com. Poddomény vyžadují samostatné záznamy, které je třeba ověřit." }, "removeDomain": { - "message": "Remove domain" + "message": "Odebrat doménu" }, "removeDomainWarning": { - "message": "Removing a domain cannot be undone. Are you sure you want to continue?" + "message": "Odebrání domény není možné vrátit. Opravdu chcete pokračovat?" }, "domainRemoved": { - "message": "Domain removed" + "message": "Doména byla odebrána" }, "domainSaved": { - "message": "Domain saved" + "message": "Doména byla uložena" }, "domainVerified": { - "message": "Domain verified" + "message": "Doména byla ověřena" }, "duplicateDomainError": { - "message": "You can't claim the same domain twice." + "message": "Nemůžete nárokovat stejnou doménu dvakrát." }, "domainNotAvailable": { - "message": "Someone else is using $DOMAIN$. Use a different domain to continue.", + "message": "Někdo jiný používá $DOMAIN$. Použijte jinou doménu pro pokračování.", "placeholders": { "DOMAIN": { "content": "$1", @@ -6355,7 +6355,7 @@ } }, "domainNotVerified": { - "message": "$DOMAIN$ not verified. Check your DNS record.", + "message": "$DOMAIN$ nebyla ověřena. Zkontrolujte Váš DNS záznam.", "placeholders": { "DOMAIN": { "content": "$1", @@ -6364,28 +6364,28 @@ } }, "domainStatusVerified": { - "message": "Verified" + "message": "Ověřeno" }, "domainStatusUnverified": { - "message": "Unverified" + "message": "Neověřeno" }, "domainNameTh": { - "message": "Name" + "message": "Název" }, "domainStatusTh": { - "message": "Status" + "message": "Stav" }, "lastChecked": { - "message": "Last checked" + "message": "Posední kontrola" }, "editDomain": { - "message": "Edit domain" + "message": "Upravit doménu" }, "domainFormInvalid": { - "message": "There are form errors that need your attention" + "message": "Existují chyby ve formulářích, které vyžadují Vaši pozornost" }, "addedDomain": { - "message": "Added domain $DOMAIN$", + "message": "Přidána doména $DOMAIN$", "placeholders": { "DOMAIN": { "content": "$1", @@ -6394,7 +6394,7 @@ } }, "removedDomain": { - "message": "Removed domain $DOMAIN$", + "message": "Odebrána doména $DOMAIN$", "placeholders": { "DOMAIN": { "content": "$1", @@ -6403,7 +6403,7 @@ } }, "domainVerifiedEvent": { - "message": "$DOMAIN$ verified", + "message": "$DOMAIN$ byla ověřena", "placeholders": { "DOMAIN": { "content": "$1", @@ -6412,7 +6412,7 @@ } }, "domainNotVerifiedEvent": { - "message": "$DOMAIN$ not verified", + "message": "$DOMAIN$ nebyla ověřena", "placeholders": { "DOMAIN": { "content": "$1", @@ -6421,46 +6421,46 @@ } }, "membersColumnHeader": { - "message": "Member/Group" + "message": "Člen/Skupina" }, "groupAndMemberColumnHeader": { - "message": "Member" + "message": "Člen" }, "selectGroupsAndMembers": { - "message": "Select groups and members" + "message": "Zvolte skupiny a členy" }, "selectGroups": { - "message": "Select groups" + "message": "Zvolte skupiny" }, "userPermissionOverrideHelper": { - "message": "Permissions set for a member will replace permissions set by that member's group" + "message": "Oprávnění nastavená pro člena nahradí oprávnění nastavená skupinou tohoto člena" }, "noMembersOrGroupsAdded": { - "message": "No members or groups added" + "message": "Nebyli přidáni žádní členové ani skupiny" }, "deleted": { - "message": "Deleted" + "message": "Smazáno" }, "memberStatusFilter": { - "message": "Member status filter" + "message": "Filtr stavu člena" }, "inviteMember": { - "message": "Invite member" + "message": "Pozvat uživatele" }, "needsConfirmation": { - "message": "Needs confirmation" + "message": "Vyžaduje potvrzení" }, "memberRole": { - "message": "Member role" + "message": "Role člena" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "Více od Bitwardenu" }, "switchProducts": { - "message": "Switch products" + "message": "Přepnout produkty" }, "freeOrgInvLimitReachedManageBilling": { - "message": "Free organizations may have up to $SEATCOUNT$ members. Upgrade to a paid plan to invite more members.", + "message": "Bezplatné organizace mohou mít až $SEATCOUNT$ členů. Chcete-li pozvat více členů, přejděte na placený plán.", "placeholders": { "seatcount": { "content": "$1", @@ -6469,7 +6469,7 @@ } }, "freeOrgInvLimitReachedNoManageBilling": { - "message": "Free organizations may have up to $SEATCOUNT$ members. Contact your organization owner to upgrade.", + "message": "Bezplatné organizace mohou mít až $SEATCOUNT$ členů. Pro aktualizaci kontaktujte majitele organizace.", "placeholders": { "seatcount": { "content": "$1", @@ -6478,7 +6478,7 @@ } }, "freeOrgMaxCollectionReachedManageBilling": { - "message": "Free organizations may have up to $COLLECTIONCOUNT$ collections. Upgrade to a paid plan to add more collections.", + "message": "Bezplatné organizace mohou mít až $COLLECTIONCOUNT$ kolekcí. Chcete-li přidat více kolekcí, přejděte na placený tarif.", "placeholders": { "COLLECTIONCOUNT": { "content": "$1", @@ -6487,7 +6487,7 @@ } }, "freeOrgMaxCollectionReachedNoManageBilling": { - "message": "Free organizations may have up to $COLLECTIONCOUNT$ collections. Contact your organization owner to upgrade.", + "message": "Bezplatné organizace mohou mít až $COLLECTIONCOUNT$ kolekcí. Pro aktualizaci kontaktujte majitele organizace.", "placeholders": { "COLLECTIONCOUNT": { "content": "$1", @@ -6499,13 +6499,13 @@ "message": "Server" }, "exportData": { - "message": "Export data" + "message": "Exportovat data" }, "exportingOrganizationSecretDataTitle": { - "message": "Exporting Organization Secret Data" + "message": "Exportování tajných dat organizace" }, "exportingOrganizationSecretDataDescription": { - "message": "Only the Secrets Manager data associated with $ORGANIZATION$ will be exported. Items in other products or from other organizations will not be included.", + "message": "Exportována budou jen tajná data organizace přidružená k položce $ORGANIZATION$. Položky v ostatních produktech a položky z jiných organizací nebudou zahrnuty.", "placeholders": { "ORGANIZATION": { "content": "$1", @@ -6514,106 +6514,118 @@ } }, "fileUpload": { - "message": "File upload" + "message": "Nahrát soubor" }, "acceptedFormats": { - "message": "Accepted Formats:" + "message": "Povolené formáty:" }, "copyPasteImportContents": { - "message": "Copy & paste import contents:" + "message": "Kopírovat a vložit obsah importu:" }, "or": { - "message": "or" + "message": "nebo" }, "licenseAndBillingManagement": { - "message": "License and billing management" + "message": "Správa licencí a fakturace" }, "automaticSync": { - "message": "Automatic sync" + "message": "Automatická synchronizace" }, "manualUpload": { - "message": "Manual upload" + "message": "Ruční nahrání" }, "manualUploadDesc": { - "message": "If you do not want to opt into billing sync, manually upload your license here." + "message": "Pokud se nechcete rozhodnout pro synchronizaci fakturace, nahrajte licenci ručně zde." }, "syncLicense": { - "message": "Sync license" + "message": "Synchronizovat licenci" }, "licenseSyncSuccess": { - "message": "Successfully synced license" + "message": "Licence byla úspěšně synchronizována" }, "licenseUploadSuccess": { - "message": "Successfully uploaded license" + "message": "Licence byla úspěšně nahrána" }, "lastLicenseSync": { - "message": "Last license sync" + "message": "Poslední synchronizace licence" }, "billingSyncHelp": { - "message": "Billing Sync help" + "message": "Nápověda pro synchronizaci fakturací" + }, + "licensePaidFeaturesHelp": { + "message": "Nápověda k placeným funkcím v licenci" + }, + "selfHostGracePeriodHelp": { + "message": "Po vypršení předplatného máte 60 dní na použití aktualizovaného licenčního souboru pro Vaši organizaci. Lhůta k odkladu končí $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } }, "uploadLicense": { - "message": "Upload license" + "message": "Nahrát licenci" }, "projectPeopleDescription": { - "message": "Grant groups or people access to this project." + "message": "Udělí skupinám nebo lidem přístup k tomuto projektu." }, "projectPeopleSelectHint": { - "message": "Type or select people or groups" + "message": "Napište nebo vyberte osoby nebo skupiny" }, "projectServiceAccountsDescription": { - "message": "Grant service accounts access to this project." + "message": "Udělí servisním účtům přístup k tomuto projektu." }, "projectServiceAccountsSelectHint": { - "message": "Type or select service accounts" + "message": "Napište nebo vyberte servisní účty" }, "projectEmptyPeopleAccessPolicies": { - "message": "Add people or groups to start collaborating" + "message": "Přidejte lidi nebo skupiny a začněte spolupracovat" }, "projectEmptyServiceAccountAccessPolicies": { - "message": "Add service accounts to grant access" + "message": "Přidejte servisní účty pro udělení přístupu" }, "serviceAccountPeopleDescription": { - "message": "Grant groups or people access to this service account." + "message": "Udělí skupinám nebo lidem přístup k tomuto servisnímu účtu." }, "serviceAccountProjectsDescription": { - "message": "Assign projects to this service account. " + "message": "Přiřaďte projekty k tomuto účtu služby. " }, "serviceAccountEmptyProjectAccesspolicies": { - "message": "Add projects to grant access" + "message": "Přidat projekty pro udělení přístupu" }, "canReadWrite": { - "message": "Can read, write" + "message": "Může číst, zapisovat" }, "groupSlashUser": { - "message": "Group/User" + "message": "Skupina/Uživatel" }, "lowKdfIterations": { - "message": "Low KDF Iterations" + "message": "Nízke iterace KDF" }, "updateLowKdfIterationsDesc": { "message": "Aktualizujte své nastavení šifrování tak, aby splňovalo nová bezpečnostní doporučení a zlepšilo ochranu účtu." }, "changeKdfLoggedOutWarning": { - "message": "Proceeding will log you out of all active sessions. You will need to log back in and complete two-step login setup. We recommend exporting your vault before changing your encryption settings to prevent data loss." + "message": "Pokračováním se odhlásíte ze všech aktivních relací. Budete se muset znovu přihlásit a dokončit nastavení dvoufázového přihlášení. Před změnou nastavení šifrování doporučujeme exportovat trezor, aby nedošlo ke ztrátě dat." }, "secretsManagerBeta": { - "message": "Secrets Manager Beta" + "message": "Správce tajných klíčů v programu Beta" }, "secretsManagerBetaDesc": { - "message": "Enable user access to the Secrets Manager at no charge during the Beta program." + "message": "Povolí přístup uživatele ke správě tajných klíčů zdarma v rámci programu Beta." }, "userAccessSecretsManager": { - "message": "This user can access the Secrets Manager Beta" + "message": "Tento uživatel může přistupovat ke správci tajných klíčů v rámci programu Beta" }, "important": { - "message": "Important:" + "message": "Důležité:" }, "viewAll": { - "message": "View all" + "message": "Zobrazit vše" }, "showingPortionOfTotal": { - "message": "Showing $PORTION$ of $TOTAL$", + "message": "Zobrazování $PORTION$ z $TOTAL$", "placeholders": { "portion": { "content": "$1", @@ -6626,16 +6638,16 @@ } }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "Vyřešte chyby níže a zkuste to znovu." }, "description": { - "message": "Description" + "message": "Popis" }, "errorReadingImportFile": { - "message": "An error occurred when trying to read the import file" + "message": "V průběhu pokusu o přečtení souboru s importem se vyskytla chyba" }, "accessedSecret": { - "message": "Accessed secret $SECRET_ID$.", + "message": "Přistoupeno k tajnému klíči $SECRET_ID$.", "placeholders": { "secret_id": { "content": "$1", @@ -6648,29 +6660,29 @@ "description": "Software Development Kit" }, "createSecret": { - "message": "Create a secret" + "message": "Vytvořit tajný klíč" }, "createProject": { - "message": "Create a project" + "message": "Vytvořit projekt" }, "createServiceAccount": { - "message": "Create a service account" + "message": "Vytvořit účet služby" }, "downloadThe": { - "message": "Download the", + "message": "Stáhnout", "description": "Link to a downloadable resource. This will be used as part of a larger phrase. Example: Download the Secrets Manager CLI" }, "smCLI": { "message": "Secrets Manager CLI" }, "importSecrets": { - "message": "Import secrets" + "message": "Importovat tajné klíče" }, "getStarted": { - "message": "Get started" + "message": "Začínáme" }, "complete": { - "message": "$COMPLETED$/$TOTAL$ Complete", + "message": "Dokončeno $COMPLETED$/$TOTAL$", "placeholders": { "COMPLETED": { "content": "$1", @@ -6683,70 +6695,70 @@ } }, "restoreSecret": { - "message": "Restore secret" + "message": "Obnovit tajný klíč" }, "restoreSecrets": { - "message": "Restore secrets" + "message": "Obnovit tajné klíče" }, "restoreSecretPrompt": { - "message": "Are you sure you want to restore this secret?" + "message": "Opravdu chcete obnovit tento tajný klíč?" }, "restoreSecretsPrompt": { - "message": "Are you sure you want to restore these secrets?" + "message": "Opravdu chcete obnovit tyto tajné klíče?" }, "secretRestoredSuccessToast": { - "message": "Secret restored" + "message": "Tajný klíč byl obnoven" }, "secretsRestoredSuccessToast": { - "message": "Secrets restored" + "message": "Tajné klíče byly obnoveny" }, "selectionIsRequired": { - "message": "Selection is required." + "message": "Je vyžadován výběr." }, "secretsManagerSubscriptionDesc": { - "message": "Turn on organization access to the Secrets Manager at no charge during the Beta program. Users can be granted access to the Beta in Members." + "message": "Zapněte přístup organizace ke správci tajných klíčů zdarma během programu Beta. Uživatelé mohou získat přístup k betaverzi v sekci Členové." }, "secretsManagerEnable": { - "message": "Enable Secrets Manager Beta" + "message": "Povolit program Beta pro správce tajných klíčů" }, "saPeopleWarningTitle": { - "message": "Access tokens still available" + "message": "Přístupové tokeny jsou stále k dispozici" }, "saPeopleWarningMessage": { - "message": "Removing people from a service account does not remove the access tokens they created. For security best practice, it is recommended to revoke access tokens created by people removed from a service account." + "message": "Odebráním osob z účtu služby se neodeberou přístupové tokeny, které tyto osoby vytvořily. V rámci osvědčených bezpečnostních postupů se doporučuje zrušit přístupové tokeny vytvořené osobami odebranými z účtu služby." }, "smAccessRemovalWarningProjectTitle": { - "message": "Remove access to this project" + "message": "Odebrat přístup k tomuto projektu" }, "smAccessRemovalWarningProjectMessage": { - "message": "This action will remove your access to the project." + "message": "Tato akce odebere Váš přístup k projektu." }, "smAccessRemovalWarningSaTitle": { - "message": "Remove access to this service account" + "message": "Odebrat přístup k tomuto účtu služby" }, "smAccessRemovalWarningSaMessage": { - "message": "This action will remove your access to the service account." + "message": "Tato akce odebere Váš přístup k účtu služby." }, "removeAccess": { - "message": "Remove access" + "message": "Odebrat přístup" }, "checkForBreaches": { - "message": "Check known data breaches for this password" + "message": "Zkontrolovat heslo, zda nebylo odhaleno" }, "exposedMasterPassword": { - "message": "Exposed Master Password" + "message": "Odhalené hlavní heslo" }, "exposedMasterPasswordDesc": { - "message": "Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?" + "message": "Heslo bylo nalezeno mezi odhalenými hesly. K zabezpečení Vašeho účtu používejte jedinečné heslo. Opravdu chcete používat odhalené heslo?" }, "weakAndExposedMasterPassword": { - "message": "Weak and Exposed Master Password" + "message": "Slabé a odhalené hlavní heslo" }, "weakAndBreachedMasterPasswordDesc": { - "message": "Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?" + "message": "Slabé heslo bylo nalezeno mezi odhalenými hesly. K zabezpečení Vašeho účtu používejte silné a jedinečné heslo. Opravdu chcete používat toto heslo?" }, "characterMinimum": { - "message": "$LENGTH$ character minimum", + "message": "Alespoň $LENGTH$ znaků", "placeholders": { "length": { "content": "$1", @@ -6755,7 +6767,7 @@ } }, "masterPasswordMinimumlength": { - "message": "Master password must be at least $LENGTH$ characters long.", + "message": "Hlavní heslo musí obsahovat alespoň $LENGTH$ znaků.", "placeholders": { "length": { "content": "$1", @@ -6764,18 +6776,29 @@ } }, "dismiss": { - "message": "Dismiss" + "message": "Zavřít" }, "notAvailableForFreeOrganization": { - "message": "Tato funkce není dostupná pro bezplatné organizace. Pro upgrade kontaktujte vlastníka organizace." + "message": "Tato funkce není dostupná pro bezplatné organizace. Pro aktualizaci kontaktujte vlastníka organizace." }, "smProjectSecretsNoItemsNoAccess": { - "message": "Obraťte se na správce Vaší organizace pro správu tajemství pro tento projekt.", + "message": "Obraťte se na správce Vaší organizace pro správu tajných klíčů pro tento projekt.", "description": "The message shown to the user under a project's secrets tab when the user only has read access to the project." }, "enforceOnLoginDesc": { "message": "Bude vyžadovat od stávajících členů, aby změnili svá hesla" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Nemáte oprávnění tento projekt smazat", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index 7872a69084..13e7f1be72 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index 224d5c91bb..7557309f92 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Hjælp til faktureringssynk" }, + "licensePaidFeaturesHelp": { + "message": "Hjælp til licensbetalte funktioner" + }, + "selfHostGracePeriodHelp": { + "message": "Ved abonnementsudløb kan der indenfor 60 dage føjes en opdateret licensfil til organisationen. Henstandsperioden udløber pr. $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload licens" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Kræv, at eksisterende medlemmer ændrer deres adgangskoder" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Ingen tilladelse til at slette dette objekt", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 3aa6a7a10b..cdd1be0203 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -5227,7 +5227,7 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Verbinde die Anmeldung über SSO mit deinem selbst gehosteten Entschlüsselungsschlüssel-Server. Mit dieser Option müssen Mitglieder ihre Master-Passwörter nicht verwenden, um Tresordaten zu entschlüsseln.", "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": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Hilfe zur Rechnungssynchronisation" }, + "licensePaidFeaturesHelp": { + "message": "Hilfe zur Lizenzierung von bezahlten Funktionen" + }, + "selfHostGracePeriodHelp": { + "message": "Nachdem dein Abonnement abgelaufen ist, hast du 60 Tage Zeit, um eine aktualisierte Lizenzdatei für deine Organisation anzuwenden. Die Nachfrist endet am $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Lizenz hochladen" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Bestehende Mitglieder auffordern, ihre Passwörter zu ändern" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Dir fehlen die Berechtigungen, dieses Projekt zu löschen.", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,7 +6811,7 @@ "message": "KDF-Einstellungen aktualisieren" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Vertrauenswürdige Geräteverschlüsselung" }, "memberDecryptionTdeDescStart": { "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index 5c6124f6b2..5afe16696a 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Μεταφόρτωση άδειας" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 646285b5c7..8dde1d4449 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload licence" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index a40eb4b58c..90ba58b1dc 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 3ae4d00f05..33e2dfed40 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index b83ca17686..159365557e 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Ayuda de sincronización de facturación" }, + "licensePaidFeaturesHelp": { + "message": "Ayuda a las funciones por licencia premium" + }, + "selfHostGracePeriodHelp": { + "message": "Después de que caduque su suscripción, tiene 60 días para aplicar un archivo de licencia actualizado a su organización. El periodo de gracia termina $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Subir licencia" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Requiere que los miembros existentes cambien sus contraseñas" }, + "region": { + "message": "Región" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "EEUU", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "No tiene permisos para eliminar este proyecto", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index 99341480e5..17ec0414d2 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index b26b182c82..572183c14c 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index 9fc68a99b4..e25da8c824 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -1256,7 +1256,7 @@ "message": "داده‌ها با موفقیت درون ریزی شد" }, "importSuccessNumberOfItems": { - "message": "A total of $AMOUNT$ items were imported.", + "message": "تعداد $AMOUNT$ مورد وارد شده است.", "placeholders": { "amount": { "content": "$1", @@ -2029,7 +2029,7 @@ "message": "لغو اشتراک" }, "subscriptionExpiration": { - "message": "Subscription expiration" + "message": "انقضای اشتراک" }, "subscriptionCanceled": { "message": "اشتراک شما لغو گردید." @@ -2751,7 +2751,7 @@ } }, "viewCollectionWithName": { - "message": "View collection - $NAME$", + "message": "مشاهده مجموعه - $NAME$", "placeholders": { "name": { "content": "$1", @@ -2760,7 +2760,7 @@ } }, "editItemWithName": { - "message": "Edit item - $NAME$", + "message": "ویرایش مجموعه - $NAME$", "placeholders": { "name": { "content": "$1", @@ -3144,7 +3144,7 @@ "message": "زمانی که یک سرپرست عضویت شما را تأیید کرد، می‌توانید به این سازمان دسترسی داشته باشید. زمانی که این اتفاق بیفتد، یک ایمیل برای شما ارسال خواهیم کرد." }, "inviteInitAcceptedDesc": { - "message": "You can now access this organization." + "message": "اکنون می‌توانید به این سازمان دسترسی داشته باشید." }, "inviteAcceptFailed": { "message": "قادر به پذیرش دعوت نیست. از مدیر سازمان بخواهید دعوتنامه جدیدی ارسال کند." @@ -4831,7 +4831,7 @@ "message": "کلمه عبور اصلی شما الزامات سیاست این سازمان را برآورده نمی‌کند. برای پیوستن به سازمان، باید کلمه عبور اصلی خود را هم اکنون به‌روز کنید. ادامه، شما را از نشست فعلی خود خارج می‌کند و از شما می‌خواهد دوباره وارد سیستم شوید. نشست‌های فعال در دستگاه‌های دیگر ممکن است تا یک ساعت فعال بمانند." }, "updateWeakMasterPasswordWarning": { - "message": "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "کلمه عبور اصلی شما با یک یا چند سیاست سازمان‌تان مطابقت ندارد. برای دسترسی به گاوصندوق، باید همین حالا کلمه عبور اصلی خود را به‌روز کنید. در صورت ادامه، شما از نشست فعلی خود خارج می‌شوید و باید دوباره وارد سیستم شوید. نشست فعال در دستگاه های دیگر ممکن است تا یک ساعت همچنان فعال باقی بمانند." }, "maximumVaultTimeout": { "message": "متوقف شدن گاو‌صندوق" @@ -4865,7 +4865,7 @@ } }, "vaultTimeoutPolicyWithActionInEffect": { - "message": "Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is $HOURS$ hour(s) and $MINUTES$ minute(s). Your vault timeout action is set to $ACTION$.", + "message": "سیاست‌های سازمانتان بر مهلت زمانی گاوصندوق شما تأثیر می‌گذارد. حداکثر زمان مجاز گاوصندوق $HOURS$ ساعت و $MINUTES$ دقیقه است. عملگر مهلت زمانی گاوصندوق شما روی $ACTION$ تنظیم شده است.", "placeholders": { "hours": { "content": "$1", @@ -4882,7 +4882,7 @@ } }, "vaultTimeoutActionPolicyInEffect": { - "message": "Your organization policies have set your vault timeout action to $ACTION$.", + "message": "سباست‌های سازمان شما، عملگر زمان‌بندی گاوصندوق شما را روی $ACTION$ تنظیم کرده است.", "placeholders": { "action": { "content": "$1", @@ -4918,7 +4918,7 @@ "message": "پر کردن خودکار را فعال کنید" }, "activateAutofillPolicyDesc": { - "message": "Activate the auto-fill on page load setting on the browser extension for all existing and new members." + "message": "تنظیم پر کردن خودکار در بارگذاری صفحه را در افزونه مرورگر برای همه اعضای موجود و جدید فعال کنید." }, "experimentalFeature": { "message": "وب‌سایت‌های در معرض خطر یا نامعتبر می‌توانند از پر کردن خودکار در بارگذاری صفحه سوء استفاده کنند." @@ -5227,15 +5227,15 @@ "message": "رابط کلید" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "ورود به سیستم با SSO را به سرور کلید رمزگشایی خود میزبانی شده متصل کنید. با استفاده از این گزینه، اعضا نیازی به استفاده از کلمه عبور اصلی خود برای رمزگشایی داده‌های گاوصندوق ندارند. ", "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": { - "message": "require SSO authentication and single organization policies", + "message": "به احراز هویت SSO و سیاست‌های سازمانی واحد نیاز دارد", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "برای راه اندازی رمزگشایی Key Connector مورد نیاز است. برای راهنمایی راه اندازی با پشتیبانی Bitwarden تماس بگیرید.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -5453,7 +5453,7 @@ "description": "This is used by screen readers to indicate the organization that is currently being shown to the user." }, "accountLoggedInAsName": { - "message": "Account: Logged in as $NAME$", + "message": "حساب کاربری: با نام $NAME$ وارد شده‌اید", "placeholders": { "name": { "content": "$1", @@ -5683,7 +5683,7 @@ } }, "inputMinValue": { - "message": "Input value must be at least $MIN$.", + "message": "مقدار ورودی باید حداقل $MIN$ باشد.", "placeholders": { "min": { "content": "$1", @@ -5692,7 +5692,7 @@ } }, "inputMaxValue": { - "message": "Input value must not exceed $MAX$.", + "message": "مقدار ورودی نباید از $MAX$ تجاوز کند.", "placeholders": { "max": { "content": "$1", @@ -5970,7 +5970,7 @@ } }, "deleteServiceAccountToast": { - "message": "Service account deleted" + "message": "حساب سرویس حذف شد" }, "deleteServiceAccountsToast": { "message": "حساب‌های سرویس حذف شد" @@ -6132,7 +6132,7 @@ "description": "Title for the section displaying access tokens." }, "newAccessToken": { - "message": "New access token", + "message": "توکن دسترسی جدید", "description": "Button label for creating a new access token." }, "expires": { @@ -6198,7 +6198,7 @@ "description": "Toast message after deleting one or multiple access tokens." }, "noAccessTokenSelected": { - "message": "No access token selected to revoke", + "message": "هیچ توکن دسترسی برای لغو انتخاب نشده است", "description": "Toast error message after trying to delete access tokens but not selecting any access tokens." }, "submenu": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "راهنمای همگام‌سازی صورتحساب" }, + "licensePaidFeaturesHelp": { + "message": "ویژگی‌های پولی مجوز کمک می‌کند" + }, + "selfHostGracePeriodHelp": { + "message": "پس از انقضای اشتراک شما، 60 روز فرصت دارید تا فایل مجوز به روز شده را در سازمان خود اعمال کنید. پایان دوره مهلت $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "بارگذاری مجوز" }, @@ -6592,10 +6604,10 @@ "message": "تکرار KDF کم" }, "updateLowKdfIterationsDesc": { - "message": "Update your encryption settings to meet new security recommendations and improve account protection." + "message": "تنظیمات رمزگذاری خود را برای رعایت توصیه‌های امنیتی جدید و بهبود حفاظت از حساب به‌روزرسانی کنید." }, "changeKdfLoggedOutWarning": { - "message": "Proceeding will log you out of all active sessions. You will need to log back in and complete two-step login setup. We recommend exporting your vault before changing your encryption settings to prevent data loss." + "message": "ادامه، شما را از تمام نشست‌های فعال خارج می‌کند. شما باید دوباره وارد شوید و راه اندازی دو مرحله ای ورود را تکمیل کنید. توصیه می‌کنیم قبل از تغییر در تنظیمات رمزگذاری برای جلوگیری از، از دست رفتن داده‌ها، گاوصندوق خود را برون ریزی کنید." }, "secretsManagerBeta": { "message": "بتا مدیر اسرار" @@ -6767,39 +6779,50 @@ "message": "نادیده گرفتن" }, "notAvailableForFreeOrganization": { - "message": "This feature is not available for free organizations. Contact your organization owner to upgrade." + "message": "این ویژگی برای سازمان‌های رایگان در دسترس نیست. برای ارتقا با مالک سازمان خود تماس بگیرید." }, "smProjectSecretsNoItemsNoAccess": { - "message": "Contact your organization's admin to manage secrets for this project.", + "message": "برای مدیریت اسرار این پروژه با سرپرست سازمان خود تماس بگیرید.", "description": "The message shown to the user under a project's secrets tab when the user only has read access to the project." }, "enforceOnLoginDesc": { - "message": "Require existing members to change their passwords" + "message": "از اعضای موجود بخواهید کلمه‌های عبور خود را تغییر دهند" + }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" }, "smProjectDeleteAccessRestricted": { - "message": "You don't have permissions to delete this project", + "message": "شما مجوز حذف این پروژه را ندارید", "description": "The individual description shown to the user when the user doesn't have access to delete a project." }, "smProjectsDeleteBulkConfirmation": { - "message": "The following projects can not be deleted. Would you like to continue?", + "message": "پروژه‌های زیر قابل حذف نیستند. آیا می‌خواهید ادامه دهید؟", "description": "The message shown to the user when bulk deleting projects and the user doesn't have access to some projects." }, "updateKdfSettings": { - "message": "Update KDF settings" + "message": "تنظیمات KDF را به‌روز کنید" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "رمزگذاری دستگاه مورد اعتماد" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "پس از احراز هویت، اعضا با استفاده از کلید ذخیره شده در دستگاه خود، داده‌های گاوصندوق را رمزگشایی می‌کنند.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "سیاست بازنشانی کلمه عبور اصلی", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "با ثبت نام خودکار زمانی که از این گزینه استفاده می‌شود روشن می‌شود.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 0f136b0519..6f64031de3 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -2029,7 +2029,7 @@ "message": "Irtisano tilaus" }, "subscriptionExpiration": { - "message": "Tilauksen päättyminen" + "message": "Tilaus päättyy" }, "subscriptionCanceled": { "message": "Tilaus irtisanottiin." @@ -2445,7 +2445,7 @@ "message": "Tapahtumalokit" }, "people": { - "message": "Ihmiset" + "message": "Henkilöt" }, "policies": { "message": "Käytännöt" @@ -5227,15 +5227,15 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Liitä kertakirjautuminen itse ylläpitämääsi salauksenpurun avainpalvelimeen. Tätä valintaa käyttämällä jäsenten ei tarvitse käyttää pääsalasanojaan holvin salauksen purkuun.", "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": { - "message": "require SSO authentication and single organization policies", + "message": "\"Vaadi todennus kertakirjautumisella\" ja \"Yksittäinen organisaatio\" -käytännöt", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "vaaditaan Key Connector -salauksenpurun käyttöönottoon. Ole yhteydessä Bitwardenin asiakaspalveluun saadaksesi apua määritykseen.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6198,7 +6198,7 @@ "description": "Toast message after deleting one or multiple access tokens." }, "noAccessTokenSelected": { - "message": "Käyttötunnistetta ei ole valittu kumottavaksi", + "message": "Mitätöitäviä käyttötunnisteita ei valittu", "description": "Toast error message after trying to delete access tokens but not selecting any access tokens." }, "submenu": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Laskutuksen synkronoinnin ohje" }, + "licensePaidFeaturesHelp": { + "message": "Maksullisen lisenssin oiminaisuusopas" + }, + "selfHostGracePeriodHelp": { + "message": "Kun tilauksesi päättyy, sinulla on 60 päivää aikaa päivittää organisaatiosi lisenssitiedosto ajan tasalle. Varoaika päättyy $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Tallenna lisenssi" }, @@ -6635,7 +6647,7 @@ "message": "Tuontitiedostoa luettaessa tapahtui virhe." }, "accessedSecret": { - "message": "Salaisuus avattiin $SECRET_ID$.", + "message": "Avasi salaisuuden $SECRET_ID$.", "placeholders": { "secret_id": { "content": "$1", @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Vaadi nykyisiä jäseniä vaihtamaan salasanansa" }, + "region": { + "message": "Alue" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Käyttöoikeutesi eivät salli tämän projektin poistamista", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "Päivitä KDF-asetukset" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Luotettu laitesalaus" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Kun jäsenet on todennettu, he voivat purkaa holvin salauksen heidän laitteillaan säilytettävällä avaimella.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "Pääsalasanan palautuskäytäntö", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "automaattisella liitoksella otetaan käyttöön tätä valintaa käytettäessä.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index 866cc9f5c9..0e773217e8 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Tulong sa Pagsingil Sync" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Mag-upload ng lisensya" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index 2210690eb7..dfd0090d79 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Aide sur la Synchronisation de la Facturation" }, + "licensePaidFeaturesHelp": { + "message": "Aide sur les fonctionnalités payantes de la licence" + }, + "selfHostGracePeriodHelp": { + "message": "Après l'expiration de votre abonnement, vous avez 60 jours pour appliquer un fichier de licence mis à jour à votre organisation. La période de grâce se termine le $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Téléverser la licence" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Exiger que les membres existants changent leurs mots de passe" }, + "region": { + "message": "Région" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Vous n'avez pas les droits pour supprimer ce projet", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 7872a69084..13e7f1be72 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index a13e1a7b02..a44d6b8bec 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index aa05de57df..b74b448b9c 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 375d11fa13..d3c6a469f0 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Pomoć za sinkronizaciju naplate" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Prenesi licencu" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 02a483debe..2dd2fa6b9b 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -5227,15 +5227,15 @@ "message": "Kulcskapcsoló" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Kapcsoljuk az egyszeri bejelentkezést a saját üzemeltetésű visszafejtési kulcsszerveréhez. Ezzel a lehetőséggel a tagoknak nem kell használniuk fő jelszavaikat a tárolóadatok visszafejtéséhez.", "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": { - "message": "require SSO authentication and single organization policies", + "message": "SSO-hitelesítést és önálló szervezeti szabályzatot igényelnek", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "szükségesek a Key Connector visszafejtésének beállításához. Beállítási segítségért forduljunk a Bitwarden ügyfélszolgálatához.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Számlázási szinkronizálás súgó" }, + "licensePaidFeaturesHelp": { + "message": "Licensz fizetős funkciók súgó" + }, + "selfHostGracePeriodHelp": { + "message": "Az előfizetés lejárta után 60 nap áll rendelkezésére a frissített licenszfájl alkalmazásához a szervezetben. A türelmi időszak lejárata: $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Licensz letöltése" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "A meglévő tagoknak meg kell változtatniuk jelszavaikat." }, + "region": { + "message": "Régió" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Nincs jogosulltság ezen projekt törléséhez.", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "KDF beállítások frissítése" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Megbízható eszköztitkosítás" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "A hitelesítés után a tagok az eszközükön tárolt kulccsal visszafejtik a tároló adatait.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "mesterjelszó alaphelyzetbe állítási szabályzat", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "automatikus regisztrációval bekapcsolásra kerül ezen opció használatával.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 1d65434418..99a3acdd86 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index aa02e33f5a..c4eb7b6b5a 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Aiuto per la sincronizzazione della fatturazione" }, + "licensePaidFeaturesHelp": { + "message": "Guida alle funzionalità a pagamento con licenza" + }, + "selfHostGracePeriodHelp": { + "message": "Dopo che il tuo abbonamento scade, hai 60 giorni per applicare un file di licenza aggiornato alla tua organizzazione. Il periodo di grazia termina il $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Carica licenza" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Obbliga i membri esistenti a cambiare le loro password" }, + "region": { + "message": "Regione" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Non hai l'autorizzazione per eliminare questo progetto", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index a3193f034a..b58fad1d1e 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -5227,15 +5227,15 @@ "message": "キーコネクター" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "SSO でログインして自己ホスト型の復号キーサーバーに接続します。このオプションを使用すると、メンバーは保管庫のデータを復号するためにマスターパスワードを使用する必要はありません。", "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": { - "message": "require SSO authentication and single organization policies", + "message": "SSO 認証と単一の組織ポリシーが必要です", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "キーコネクターの復号のセットアップに必要です。Bitwarden サポートにお問い合わせください。", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "請求同期のヘルプ" }, + "licensePaidFeaturesHelp": { + "message": "有料機能ライセンスのヘルプ" + }, + "selfHostGracePeriodHelp": { + "message": "サブスクリプションの有効期限が切れた後、60日以内なら期限を更新したライセンスファイルを組織に適用できます。猶予期間は $GRACE_PERIOD_END_DATE$ までです。", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "ライセンスをアップロード" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "パスワードを変更するには、メンバーが存在しないといけません" }, + "region": { + "message": "リージョン" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "米国", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "このプロジェクトを削除する権限がありません", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "KDF の設定を更新する" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "信頼できるデバイスの暗号化" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "認証が完了すると、メンバーはデバイスに保存されているキーを使用して保管庫のデータを復号します。", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "マスターパスワードのリセットポリシー", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "このオプションを使用すると、自動登録が有効になります。", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index 8da28142fc..9331bfc82e 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index 7872a69084..13e7f1be72 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index 8c463f8637..8f6407f757 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 2b70172330..007d37be7c 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 09c4b21f75..bb763b2d72 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -5227,15 +5227,15 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Savienot pierakstīšanos ar vienoto pieteikšanos pašizvietotā atšifrēšanas atslēgu serverī. Šī iespēja nodrošina, ka dalībniekiem nebūs nepieciešama galvenā parole, lai atšifrētu glabātavas saturu.", "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": { - "message": "require SSO authentication and single organization policies", + "message": "Pieprasīt vienoto pieteikšanos un vienas apvienības nosacījumi", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "ir nepieciešami, lai uzstādītu Key Connector atšifrēšanu. Jāsazinās ar Bitwarden atbalstu, lai iegūtu palīdzību uzstādīšanā.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Norēķinu sinhronizācijas palīdzība" }, + "licensePaidFeaturesHelp": { + "message": "Palīdzība par licences apmaksātajām iespējām" + }, + "selfHostGracePeriodHelp": { + "message": "Pēc abonementa izbeigšanās ir 60 dienas, lai apvienībai piemērotu atjauninātu licenci. Atjaunošanas laika posms beidzas $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Augšupielādēt licenci" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Pieprasīt esošajiem dalībniekiem nomainīt to paroles" }, + "region": { + "message": "Apgabals" + }, + "eu": { + "message": "ES", + "description": "European Union" + }, + "us": { + "message": "ASV", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Nav nepieciešamo atļauju, lai izdzēstu šo projektu", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "Atjaunināt KDF iestatījumus" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Uzticamo ierīču šifrēšana" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Pēc pieteikšanās dalībnieki atšifrēs glabātavas saturu ar ierīcē glabātu atslēgu.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "Galvenās paroles atiestatīšanas nosacījums", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "ar automātisku ievietošanu sarakstā tiks ieslēgts, kad šī iespēja ir izmantota.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index 855daa89ba..b54b1a07dd 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index 7872a69084..13e7f1be72 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index 514af6b4c0..9c4d4cecd8 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Hjelp til fakturasynkronisering" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Last opp lisens" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index 058092eaf0..06fcd6e89a 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 6f8070942b..c8a99bea69 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Hulp bij facturatiesynchronisatie" }, + "licensePaidFeaturesHelp": { + "message": "Licentiehulp betaalde functionaliteit" + }, + "selfHostGracePeriodHelp": { + "message": "Als je abonnement is verlopen, heb je 60 dagen voor het toepassen van een bijgewerkt licentiebestand op je organisatie. De gratieperiode eindigt $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Licentie uploaden" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Verplicht bestaande leden hun wachtwoord te wijzigen" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Je hebt geen rechten om dit project te verwijderen", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index 9120b783cb..1f20f1b756 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index 7872a69084..13e7f1be72 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 4b33353e54..075336f612 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -5227,7 +5227,7 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Połącz logowanie za pomocą SSO z Twoim serwerem kluczy odszyfrowania. Używając tej opcji, użytkownicy nie będą musieli używać swoich haseł głównych, aby odszyfrować dane sejfu.", "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": { @@ -5235,7 +5235,7 @@ "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "są wymagane do skonfigurowania deszyfrowania Key Connector. Skontaktuj się z pomocą Bitwarden, aby uzyskać pomoc.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Pomoc synchronizacji płatności" }, + "licensePaidFeaturesHelp": { + "message": "Pomoc w zakresie płatnych funkcji licencyjnych" + }, + "selfHostGracePeriodHelp": { + "message": "Po wygaśnięciu subskrypcji masz 60 dni na dodanie zaktualizowanego pliku licencji dla Twojej organizacji. Okres karencji kończy się $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Prześlij licencję" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Wymagaj od istniejących członków zmiany haseł" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Nie masz uprawnień do usunięcia tego projektu", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "Zaktualizuj ustawienia KDF" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Szyfrowanie zaufanego urządzenia" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Po uwierzytelnieniu użytkownicy odszyfrowają dane sejfu przy użyciu klucza zapisanego na ich urządzeniu.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "Zasady resetowania hasła głównego", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "z automatycznym zapisem włączy się, gdy ta opcja jest używana.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 1b10a10c9a..ce6b449b55 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index c9aa8ba987..79aeec7ed5 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -180,7 +180,7 @@ "message": "Não atribuido" }, "noneFolder": { - "message": "Nenhuma pasta", + "message": "Em nenhuma pasta", "description": "This is the folder for uncategorized items" }, "addFolder": { @@ -297,10 +297,10 @@ "description": "Search Secure Note type" }, "searchVault": { - "message": "Pesquisar cofre" + "message": "Procurar no cofre" }, "searchMyVault": { - "message": "Search my vault" + "message": "Procurar no meu cofre" }, "searchOrganization": { "message": "Search organization" @@ -360,7 +360,7 @@ "message": "Apelido" }, "fullName": { - "message": "Nome Completo" + "message": "Nome completo" }, "address1": { "message": "Endereço 1" @@ -405,7 +405,7 @@ "message": "Ver item" }, "new": { - "message": "New", + "message": "Novo", "description": "for adding new items" }, "item": { @@ -462,7 +462,7 @@ "message": "Eu" }, "myVault": { - "message": "O meu Cofre" + "message": "O meu cofre" }, "allVaults": { "message": "Todos os Cofres" @@ -628,7 +628,7 @@ "message": "Criar conta" }, "newAroundHere": { - "message": "Novo por aqui?" + "message": "É novo por cá?" }, "startTrial": { "message": "Iniciar avaliação" @@ -658,10 +658,10 @@ "message": "A palavra-passe mestra é a palavra-passe que utiliza para aceder ao seu cofre. É muito importante que não se esqueça da sua palavra-passe mestra. Não existe maneira de recuperar a palavra-passe no caso de a esquecer." }, "masterPassImportant": { - "message": "As palavras-passe mestras não podem ser recuperadas se as esquecer!" + "message": "A palavras-passe mestra não pode ser recuperada se a esquecer!" }, "masterPassHintDesc": { - "message": "Uma dica da palavra-passe mestra pode ajudar a lembrar-se da sua palavra-passe se a esquecer." + "message": "Uma dica da palavra-passe mestra pode ajudá-lo a lembrar-se da sua palavra-passe, caso se esqueça dela." }, "reTypeMasterPass": { "message": "Reescreva a palavra-passe mestra" @@ -691,13 +691,13 @@ "message": "Endereço de email inválido." }, "masterPasswordRequired": { - "message": "A palavra-passe mestra é necessária." + "message": "É necessária a palavra-passe mestra." }, "confirmMasterPasswordRequired": { "message": "É necessário reescrever a palavra-passe mestra." }, "masterPasswordMinlength": { - "message": "Master password must be at least $VALUE$ characters long.", + "message": "A palavra-passe mestra deve ter pelo menos $VALUE$ caracteres.", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -819,7 +819,7 @@ "message": "Enviar email com o código de confirmação novamente" }, "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de início de sessão de dois passos" + "message": "Utilizar outro método de verificação de dois passos" }, "insertYubiKey": { "message": "Introduza a sua YubiKey na porta USB do seu computador, depois toque no botão da mesma." @@ -831,13 +831,13 @@ "message": "Início de sessão indisponível" }, "noTwoStepProviders": { - "message": "Esta conta tem o início de sessão de dois passos ativado, no entanto, nenhum dos provedores de início de sessão de dois passos configurados são suportados por este navegador web." + "message": "Esta conta tem a verificação de dois passos configurada, no entanto, nenhum dos fornecedores de dois passos configurados é suportado por este navegador web." }, "noTwoStepProviders2": { "message": "Por favor utilize um navegador web suportado (tal como o Chrome) e/ou adicione provedores adicionais que são melhor suportados entre navegadores web (tal como uma aplicação de autenticador)." }, "twoStepOptions": { - "message": "Opções de início de sessão de dois passos" + "message": "Opções de verificação de dois passos" }, "recoveryCodeDesc": { "message": "Perdeu o acesso a todos os seus provedores de dois passos? Utilize o seu código de recuperação para desativar todos os provedores de dois passos da sua conta." @@ -1292,7 +1292,7 @@ "message": "Selecione o ficheiro a importar" }, "chooseFile": { - "message": "Escolher Ficheiro" + "message": "Escolher ficheiro" }, "noFileChosen": { "message": "Nenhum ficheiro escolhido" @@ -1384,7 +1384,7 @@ "message": "Domínios atualizados" }, "twoStepLogin": { - "message": "Início de sessão de dois passos" + "message": "Verificação de dois passos" }, "twoStepLoginEnforcement": { "message": "Aplicação do Início de Sessão de Dois Passos" @@ -1412,7 +1412,7 @@ "message": "Ver código de recuperação" }, "providers": { - "message": "Provedores", + "message": "Fornecedores", "description": "Two-step login providers such as YubiKey, Duo, Authenticator apps, Email, etc." }, "enable": { @@ -1441,7 +1441,7 @@ "message": "Tem acesso premium" }, "alreadyPremiumFromOrg": { - "message": "Já tem acesso às funcionalidades premium por causa de uma organização da qual é um membro." + "message": "Já tem acesso a funcionalidades Premium devido a uma organização de que é membro." }, "manage": { "message": "Gerir" @@ -1653,7 +1653,7 @@ "description": "Vault health reports can be used to evaluate the security of your Bitwarden individual or organization vault." }, "orgsReportsDesc": { - "message": "Identifique e feche lacunas de segurança nas contas da sua organização ao clicar nos relatórios abaixo.", + "message": "Identifique e elimine as lacunas de segurança nas contas da sua organização ao clicar nos relatórios abaixo.", "description": "Vault health reports can be used to evaluate the security of your Bitwarden individual or organization vault." }, "unsecuredWebsitesReport": { @@ -1892,7 +1892,7 @@ "message": "1 GB de armazenamento encriptado para anexos de ficheiros." }, "premiumSignUpTwoStep": { - "message": "Opções adicionais de início de sessão de dois passos, como YubiKey, FIDO U2F, e Duo." + "message": "Opções adicionais de verificação de dois passos, como YubiKey, FIDO U2F e Duo." }, "premiumSignUpEmergency": { "message": "Acesso de emergência" @@ -2307,7 +2307,7 @@ } }, "limitedUsers": { - "message": "Limite de $COUNT$ utilizadores (incluindo a si)", + "message": "Limite de $COUNT$ utilizadores (incluindo o próprio)", "placeholders": { "count": { "content": "$1", @@ -2490,7 +2490,7 @@ "message": "Quando um membro é revogado, já não terá acesso aos dados da organização. Para restaurar rapidamente o acesso ao membro vá para a aba Revogada." }, "removeUserConfirmationKeyConnector": { - "message": "Atenção! Este utilizador necessita do Key Connector para gerir a sua encriptação. A remoção deste utilizador da sua organização desativará permanentemente a sua conta. Esta ação não pode ser desfeita. Deseja prosseguir?" + "message": "Atenção! Este utilizador necessita do Key Connector para gerir a sua encriptação. Ao remover este utilizador da sua organização desativará permanentemente a sua conta. Esta ação não pode ser desfeita. Deseja prosseguir?" }, "externalId": { "message": "Id externa" @@ -2643,7 +2643,7 @@ "message": "Palavra-passe da conta alterada." }, "enabledUpdated2fa": { - "message": "Início de sessão em dois passos ativado/atualizado." + "message": "Verificação de dois passos guardada" }, "disabled2fa": { "message": "Início de sessão de dois passos desativado." @@ -2796,7 +2796,7 @@ } }, "autofilledItemId": { - "message": "Item $ID$ auto-preenchido.", + "message": "Item $ID$ preenchido automaticamente.", "placeholders": { "id": { "content": "$1", @@ -3186,13 +3186,13 @@ "message": "Minha organização" }, "organizationInfo": { - "message": "Informações da Organização" + "message": "Informações da organização" }, "deleteOrganization": { "message": "Eliminar organização" }, "deletingOrganizationContentWarning": { - "message": "Digite a senha mestra para confirmar a exclusão de $ORGANIZATION$ e todos os dados associados. Os dados do cofre no $ORGANIZATION$ incluem:", + "message": "Introduza a palavra-passe mestra para confirmar a eliminação de $ORGANIZATION$ e de todos os dados associados. Os dados do cofre em $ORGANIZATION$ incluem:", "placeholders": { "organization": { "content": "$1", @@ -3345,7 +3345,7 @@ "message": "Assinatura atualizada" }, "additionalOptions": { - "message": "Opções Adicionais" + "message": "Opções adicionais" }, "additionalOptionsDesc": { "message": "Para ajuda adicional no gerenciamento da sua assinatura, entre em contato com o suporte ao cliente." @@ -4207,7 +4207,7 @@ "message": "Acesso de emergência rejeitado" }, "passwordResetFor": { - "message": "Redefinição da palavra-passe para $USER$. Pode agora iniciar sessão utilizando a nova palavra-passe.", + "message": "Palavra-passe de $USER$ redefinida. Pode agora iniciar sessão utilizando a nova palavra-passe.", "placeholders": { "user": { "content": "$1", @@ -4915,16 +4915,16 @@ "message": "Uma ou mais políticas da organização impedem que exporte o seu cofre pessoal." }, "activateAutofill": { - "message": "Activate auto-fill" + "message": "Ativar o preenchimento automático" }, "activateAutofillPolicyDesc": { - "message": "Activate the auto-fill on page load setting on the browser extension for all existing and new members." + "message": "Ative a definição do preenchimento automático no carregamento da página na extensão do navegador para todos os membros existentes e novos." }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit auto-fill on page load." + "message": "Os sites comprometidos ou não fiáveis podem explorar o preenchimento automático no carregamento da página." }, "learnMoreAboutAutofill": { - "message": "Learn more about auto-fill" + "message": "Saber mais sobre o preenchimento automático" }, "selectType": { "message": "Selecionar tipo de SSO" @@ -5161,7 +5161,7 @@ "message": "Key Connector URL" }, "sendVerificationCode": { - "message": "Send a verification code to your email" + "message": "Enviar um código de verificação para o seu e-mail" }, "sendCode": { "message": "Enviar código" @@ -5356,7 +5356,7 @@ "message": "Requested" }, "formErrorSummaryPlural": { - "message": "$COUNT$ campos acima necessitam da sua atenção.", + "message": "Os $COUNT$ campos acima precisam da sua atenção.", "placeholders": { "count": { "content": "$1", @@ -5365,7 +5365,7 @@ } }, "formErrorSummarySingle": { - "message": "1 campo acima necessita da sua atenção." + "message": "1 campo acima precisa da sua atenção." }, "fieldRequiredError": { "message": "$FIELDNAME$ é necessário.", @@ -5392,7 +5392,7 @@ "message": "Necessário se o ID da Entidade não for um URL." }, "openIdOptionalCustomizations": { - "message": "Personalizações Opcionais" + "message": "Personalizações opcionais" }, "openIdAuthorityRequired": { "message": "Required if Authority is not valid." @@ -5404,13 +5404,13 @@ "message": "A sua sessão expirou. Por favor, volte atrás e tente iniciar sessão novamente." }, "exportingPersonalVaultTitle": { - "message": "A Exportar Cofre Pessoal" + "message": "A exportar cofre pessoal" }, "exportingOrganizationVaultTitle": { - "message": "A Exportar Cofre da Organização" + "message": "A exportar cofre da organização" }, "exportingPersonalVaultDescription": { - "message": "Apenas os itens do cofre pessoal associado ao $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos.", + "message": "Apenas os itens do cofre pessoal associado a $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos.", "placeholders": { "email": { "content": "$1", @@ -5468,7 +5468,7 @@ "message": "Generator" }, "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" + "message": "O que é que gostaria de gerar?" }, "passwordType": { "message": "Password type" @@ -5572,16 +5572,16 @@ "message": "API access token" }, "deviceVerification": { - "message": "Verificação do Dispositivo" + "message": "Verificação do dispositivo" }, "enableDeviceVerification": { - "message": "Ativar a Verificação do Dispositivo" + "message": "Ativar a verificação do dispositivo" }, "deviceVerificationDesc": { "message": "Quando ativada, são enviados códigos de verificação para o seu endereço de e-mail ao iniciar sessão a partir de um dispositivo não reconhecido" }, "updatedDeviceVerification": { - "message": "Verificação do Dispositivo Atualizada" + "message": "Verificação do dispositivo atualizada" }, "areYouSureYouWantToEnableDeviceVerificationTheVerificationCodeEmailsWillArriveAtX": { "message": "Tem a certeza de que deseja ativar a Verificação do Dispositivo? Os e-mails com os códigos de verificação serão enviados para: $EMAIL$", @@ -5785,7 +5785,7 @@ "message": "-- Select --" }, "multiSelectPlaceholder": { - "message": "-- Escreva para Filtrar --" + "message": "-- Escreva para filtrar --" }, "multiSelectLoading": { "message": "A recuperar opções..." @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6755,7 +6767,7 @@ } }, "masterPasswordMinimumlength": { - "message": "Master password must be at least $LENGTH$ characters long.", + "message": "A palavra-passe mestra deve ter pelo menos $LENGTH$ caracteres.", "placeholders": { "length": { "content": "$1", @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Região" + }, + "eu": { + "message": "UE", + "description": "European Union" + }, + "us": { + "message": "EUA", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index f18a12a597..8124754397 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index 4cd29d0b01..1f0be6cf33 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Справка по синхронизации биллинга" }, + "licensePaidFeaturesHelp": { + "message": "Справка по платным лицензионным функциям" + }, + "selfHostGracePeriodHelp": { + "message": "После истечения срока действия подписки у вас есть 60 дней, чтобы применить обновленный файл лицензии к вашей организации. Льготный период заканчивается: $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Загрузить лицензию" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Требовать от существующих пользователей смены паролей" }, + "region": { + "message": "Регион" + }, + "eu": { + "message": "Европа", + "description": "European Union" + }, + "us": { + "message": "США", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "У вас недостаточно прав для удаления этого проекта", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index 5f3b655d19..23f9c3f3c0 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 71471e8a4b..06f5fe780d 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Požadovať po súčasných členoch, aby si zmenili heslo" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Na odstránenie tohto projektu nemáte oprávnenia", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index 9b39fc09eb..f5328846bc 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -1111,7 +1111,7 @@ } }, "loggedOutWarning": { - "message": "Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "Po tem dejanju boste odjavljeni in se boste morali prijaviti ponovno. Prijave na drugih napravah bodo ostale aktivne še največ eno uro." }, "emailChanged": { "message": "E-poštni naslov spremenjen" @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6595,7 +6607,7 @@ "message": "Update your encryption settings to meet new security recommendations and improve account protection." }, "changeKdfLoggedOutWarning": { - "message": "Proceeding will log you out of all active sessions. You will need to log back in and complete two-step login setup. We recommend exporting your vault before changing your encryption settings to prevent data loss." + "message": "Po tem dejanju boste odjavljeni iz vseh aktivnih sej (na vseh napravah). Prijaviti se boste morali ponovno in zaključiti nastavitev dvostopenjske prijave. Priporočamo vam, da pred tem izvozite svoje podatke, da jih v tem procesu ne bi izgubili." }, "secretsManagerBeta": { "message": "Secrets Manager Beta" @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index c43f2596e5..2424782b0c 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Помоћ синх наплате" }, + "licensePaidFeaturesHelp": { + "message": "Помоћ функције које се плаћају лиценцом" + }, + "selfHostGracePeriodHelp": { + "message": "Након што ваша претплата истекне, имате 60 дана да примените ажурирану лиценцу на Вашу организацију. Грациозни период се завршава $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Унос лиценце" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Захтевајте од постојећих чланова да промене њихове лозинке" }, + "region": { + "message": "Регион" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Немате дозволе да избришете овај пројекат", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "Ажурирати KDF подешавања" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Шифровање поузданог уређаја" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Када се аутентификују, чланови ће дешифровати податке из сефљ користећи кључ сачуван на њиховом уређају.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "политика ресетовања главне лозинке", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "са аутоматским уписом ће се укључити када се користи ова опција.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index 3b5f75bd25..cf1696e720 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index 5c4c81ae18..69a6a8ad2c 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index 7872a69084..13e7f1be72 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index 4a0ec91734..d0df03ccc2 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Upload license" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index afd0c90f90..32bb5c7394 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -5227,15 +5227,15 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "SSO ile oturum açmak için şirket içinde barındırılan şifre çözme anahtarı sunucunuza bağlayın. Bu seçenek kullanılırsa, üyelerin kasa verilerinin şifresini çözmek için ana parolalarını kullanmaları gerekmez", "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": { - "message": "require SSO authentication and single organization policies", + "message": "SSO kimlik doğrulaması ve tek kuruluş ilkeleri gerektirir", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "Anahtar Bağlayıcı şifre çözmeyi ayarlamak için gereklidir. Kurulum yardımı için Bitwarden Desteği ile iletişime geçin.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Fatura Eşitlemesi yardımı" }, + "licensePaidFeaturesHelp": { + "message": "Lisanslı ücretli özellikler yardımı" + }, + "selfHostGracePeriodHelp": { + "message": "Aboneliğiniz sona erdikten sonra, güncellenmiş bir lisans dosyasını kuruluşunuza uygulamak için 60 gününüz vardır. Ek süre $GRACE_PERIOD_END_DATE$ tarihinde sona erer.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Lisansı yükle" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Mevcut üyelerin parolalarını değiştirmelerini zorunlu tut" }, + "region": { + "message": "Bölge" + }, + "eu": { + "message": "AB", + "description": "European Union" + }, + "us": { + "message": "ABD", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "Bu projeyi silme izniniz yok", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6788,18 +6811,18 @@ "message": "KDF ayarlarını güncelle" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Güvenilir cihaz şifrelemesi" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Bir kez imliği doğrulandıktan sonra üyeler, cihazlarında saklanan bir anahtarı kullanarak kasa verilerinin şifresini çözebilir.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "ana parola sıfırlama ilkesi", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "Bu seçenek kullanıldığında otomatik kayıt ile açılacaktır.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index ba959c9b86..5d311a057b 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -2751,7 +2751,7 @@ } }, "viewCollectionWithName": { - "message": "View collection - $NAME$", + "message": "Переглянути збірку - $NAME$", "placeholders": { "name": { "content": "$1", @@ -2760,7 +2760,7 @@ } }, "editItemWithName": { - "message": "Edit item - $NAME$", + "message": "Редагувати елемент - $NAME$", "placeholders": { "name": { "content": "$1", @@ -5227,15 +5227,15 @@ "message": "Key Connector" }, "memberDecryptionKeyConnectorDescStart": { - "message": "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", + "message": "Під'єднайте вхід з SSO до свого власного сервера ключів розшифрування. Скориставшись цією можливістю, учасникам не потрібен буде головний пароль для розшифрування даних сховища.", "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": { - "message": "require SSO authentication and single organization policies", + "message": "Вимога SSO автентифікації та політик єдиної організації", "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.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "є обов'язковими для налаштування розшифрування за допомогою Key Connector. Зверніться до служби підтримки Bitwarden для отримання допомоги з налаштуванням.", "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.'" }, "keyConnectorPolicyRestriction": { @@ -5453,7 +5453,7 @@ "description": "This is used by screen readers to indicate the organization that is currently being shown to the user." }, "accountLoggedInAsName": { - "message": "Account: Logged in as $NAME$", + "message": "Обліковий запис: Вхід виконано як $NAME$", "placeholders": { "name": { "content": "$1", @@ -6198,7 +6198,7 @@ "description": "Toast message after deleting one or multiple access tokens." }, "noAccessTokenSelected": { - "message": "No access token selected to revoke", + "message": "Не вибрано токенів доступу для відкликання", "description": "Toast error message after trying to delete access tokens but not selecting any access tokens." }, "submenu": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Допомога з платіжною синхронізацією" }, + "licensePaidFeaturesHelp": { + "message": "Довідка щодо платних можливостей ліцензії" + }, + "selfHostGracePeriodHelp": { + "message": "Після завершення передплати ви матимете 60 днів, щоб застосувати оновлений файл ліцензії для організації. Пільговий період завершується $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Вивантажити ліцензію" }, @@ -6592,7 +6604,7 @@ "message": "Низький показник KDF-ітерацій" }, "updateLowKdfIterationsDesc": { - "message": "Update your encryption settings to meet new security recommendations and improve account protection." + "message": "Оновіть свої налаштування шифрування згідно з новими рекомендаціями щодо безпеки для вдосконалення захисту облікового запису." }, "changeKdfLoggedOutWarning": { "message": "Продовжуючи, ви вийдете з усіх активних сеансів. Необхідно буде повторно виконати вхід і пройти двоетапну перевірку. Перед зміною налаштувань шифрування ми рекомендуємо експортувати ваше сховище, щоб запобігти можливій втраті даних." @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Вимагати від наявних учасників змінювати паролі" }, + "region": { + "message": "Регіон" + }, + "eu": { + "message": "ЄС", + "description": "European Union" + }, + "us": { + "message": "США", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "У вас немає дозволу на видалення цього проєкту", "description": "The individual description shown to the user when the user doesn't have access to delete a project." @@ -6785,21 +6808,21 @@ "description": "The message shown to the user when bulk deleting projects and the user doesn't have access to some projects." }, "updateKdfSettings": { - "message": "Update KDF settings" + "message": "Оновити налаштування KDF" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Шифрування досвіреного пристрою" }, "memberDecryptionTdeDescStart": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Після авторизації учасники розшифровуватимуть дані сховища з використанням ключа, збереженого на їхньому пристрої.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescLink": { - "message": "master password reset policy", + "message": "Політика скидання головного пароля", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionTdeDescEnd": { - "message": "with automatic enrollment will turn on when this option is used.", + "message": "з автоматичним розгортанням увімкнеться, якщо використовується ця опція.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The master password reset policy with automatic enrollment will turn on when this option is used.'" } } diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index 5bae2a630c..9d0d958352 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Trợ giúp về Đồng Bộ Thanh Toán" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "Tải lên giấy phép" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index dd4e7801aa..36cf56e184 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -6198,7 +6198,7 @@ "description": "Toast message after deleting one or multiple access tokens." }, "noAccessTokenSelected": { - "message": "未选择要撤销的访问令牌", + "message": "未选中任何要撤销的访问令牌", "description": "Toast error message after trying to delete access tokens but not selecting any access tokens." }, "submenu": { @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "计费同步帮助" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "订阅到期后,您有 60 天时间为您的组织应用更新后的许可证文件。宽限期结束于 $GRACE_PERIOD_END_DATE$。", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "上传许可证" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "要求现有成员更改他们的密码" }, + "region": { + "message": "区域" + }, + "eu": { + "message": "欧盟", + "description": "European Union" + }, + "us": { + "message": "美国", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "您无权删除此项目", "description": "The individual description shown to the user when the user doesn't have access to delete a project." diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index 3b229d49f6..c5eb754cd1 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -6552,6 +6552,18 @@ "billingSyncHelp": { "message": "Billing Sync help" }, + "licensePaidFeaturesHelp": { + "message": "License paid features help" + }, + "selfHostGracePeriodHelp": { + "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "placeholders": { + "GRACE_PERIOD_END_DATE": { + "content": "$1", + "example": "May 12, 2024" + } + } + }, "uploadLicense": { "message": "上傳授權證" }, @@ -6776,6 +6788,17 @@ "enforceOnLoginDesc": { "message": "Require existing members to change their passwords" }, + "region": { + "message": "Region" + }, + "eu": { + "message": "EU", + "description": "European Union" + }, + "us": { + "message": "US", + "description": "United States" + }, "smProjectDeleteAccessRestricted": { "message": "You don't have permissions to delete this project", "description": "The individual description shown to the user when the user doesn't have access to delete a project." From b3e276e8d5a684a849b26dec49c28365a9ddefef Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 10:39:08 +0200 Subject: [PATCH 42/75] Autosync the updated translations (#5515) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ca/messages.json | 6 +-- apps/browser/src/_locales/nl/messages.json | 2 +- apps/browser/src/_locales/pt_PT/messages.json | 54 +++++++++---------- apps/browser/src/_locales/sl/messages.json | 18 +++---- apps/browser/store/locales/pt_PT/copy.resx | 2 +- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index e117d21790..91bbfdb48b 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -2222,17 +2222,17 @@ } }, "region": { - "message": "Region" + "message": "Regió" }, "opensInANewWindow": { "message": "S'obri en una finestra nova" }, "eu": { - "message": "EU", + "message": "UE", "description": "European Union" }, "us": { - "message": "US", + "message": "EUA", "description": "United States" } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index cf3cae05d4..68a6ba26b1 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -2225,7 +2225,7 @@ "message": "Regio" }, "opensInANewWindow": { - "message": "Opens in a new window" + "message": "Opent in een nieuw venster" }, "eu": { "message": "EU", diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 9950328204..c68d9cff8f 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden", + "message": "Bitwarden - Gestor de palavras-passe gratuito", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { @@ -38,10 +38,10 @@ "message": "Palavra-passe Mestra" }, "masterPassDesc": { - "message": "A palavra-passe mestra é a palavra-passe que utiliza para aceder ao seu cofre. É muito importante que não se esqueça da sua palavra-passe mestra. Não existe maneira de recuperar a palavra-passe no caso de a esquecer." + "message": "A palavra-passe mestra é a palavra-passe que utiliza para aceder ao seu cofre. É muito importante que não se esqueça da sua palavra-passe mestra. Não há forma de recuperar a palavra-passe no caso de a esquecer." }, "masterPassHintDesc": { - "message": "Uma dica da palavra-passe mestra pode ajudar a lembrar-se da sua palavra-passe se a esquecer." + "message": "Uma dica da palavra-passe mestra pode ajudá-lo a lembrar-se da sua palavra-passe, caso se esqueça dela." }, "reTypeMasterPass": { "message": "Re-digite a palavra-passe mestra" @@ -59,7 +59,7 @@ "message": "O meu cofre" }, "allVaults": { - "message": "Todos os Cofres" + "message": "Todos os cofres" }, "tools": { "message": "Ferramentas" @@ -89,7 +89,7 @@ "message": "Copiar código de segurança" }, "autoFill": { - "message": "Auto-preencher" + "message": "Preenchimento automático" }, "generatePasswordCopied": { "message": "Gerar Palavra-passe (copiada)" @@ -157,7 +157,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." }, "twoStepLogin": { - "message": "Início de Sessão de Dois Passos" + "message": "Verificação de dois passos" }, "logOut": { "message": "Terminar Sessão" @@ -196,7 +196,7 @@ "message": "Ajuda e feedback" }, "helpCenter": { - "message": "Centrro de ajuda do Bitwarden" + "message": "Centro de ajuda do Bitwarden" }, "communityForums": { "message": "Explorar os fóruns da comunidade do Bitwarden" @@ -279,7 +279,7 @@ "message": "Evitar caracteres ambíguos" }, "searchVault": { - "message": "Pesquisar cofre" + "message": "Procurar no cofre" }, "edit": { "message": "Editar" @@ -348,7 +348,7 @@ "message": "O seu navegador web não suporta cópia fácil da área de transferência. Em alternativa, copie manualmente." }, "verifyIdentity": { - "message": "Verificar Identidade" + "message": "Verificar identidade" }, "yourVaultIsLocked": { "message": "O seu cofre está bloqueado. Verifique a sua palavra-passe mestra para continuar." @@ -433,7 +433,7 @@ "message": "Endereço de email inválido." }, "masterPasswordRequired": { - "message": "A palavra-passe mestra é necessária." + "message": "É necessária a palavra-passe mestra." }, "confirmMasterPasswordRequired": { "message": "É necessário reescrever a palavra-passe mestra." @@ -507,7 +507,7 @@ "message": "Pode alterar a sua palavra-passe mestra no cofre web bitwarden.com. Pretende visitar o website agora?" }, "twoStepLoginConfirmation": { - "message": "O início de sessão de dois passos torna a sua conta mais segura ao requerer que verifique o seu início de sessão com outro dispositivo como uma chave de segurança, aplicação de autenticação, SMS, chamada telefónica, ou email. O início de sessão de dois passos pode ser ativado no cofre web bitwarden.com. Pretende visitar o website agora?" + "message": "A verificação de dois passos torna a sua conta mais segura, exigindo que verifique o seu início de sessão com outro dispositivo, como uma chave de segurança, aplicação de autenticação, SMS, chamada telefónica ou e-mail. A verificação de dois passos pode ser configurada em bitwarden.com. Pretende visitar o site agora?" }, "editedFolder": { "message": "Pasta editada" @@ -583,7 +583,7 @@ "message": "Pesquisar tipo" }, "noneFolder": { - "message": "Nenhuma pasta", + "message": "Em nenhuma pasta", "description": "This is the folder for uncategorized items" }, "enableAddLoginNotification": { @@ -787,7 +787,7 @@ "message": "1 GB de armazenamento encriptado para anexos de ficheiros." }, "ppremiumSignUpTwoStep": { - "message": "Opções de início de sessão de dois passos adicionais como YubiKey, FIDO U2F, e Duo." + "message": "Opções adicionais de verificação de dois passos, como YubiKey, FIDO U2F e Duo." }, "ppremiumSignUpReports": { "message": "Higiene de palavras-passe, saúde das contas, e relatórios de brechas de dados para manter o seu cofre seguro." @@ -868,7 +868,7 @@ "message": "Enviar código de verificação novamente" }, "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de início de sessão de dois passos" + "message": "Utilizar outro método de verificação de dois passos" }, "insertYubiKey": { "message": "Introduza a sua YubiKey na porta USB do seu computador, depois toque no botão da mesma." @@ -889,13 +889,13 @@ "message": "Início de sessão indisponível" }, "noTwoStepProviders": { - "message": "Esta conta tem o início de sessão de dois passos ativado, no entanto, nenhum dos provedores de início de sessão de dois passos configurados são suportados por este navegador web." + "message": "Esta conta tem a verificação de dois passos configurada, no entanto, nenhum dos fornecedores de dois passos configurados é suportado por este navegador web." }, "noTwoStepProviders2": { "message": "Por favor utilize um navegador web suportado (tal como o Chrome) e/ou adicione provedores adicionais que são melhor suportados entre navegadores web (tal como uma aplicação de autenticador)." }, "twoStepOptions": { - "message": "Opções de início de sessão de dois passos" + "message": "Opções de verificação de dois passos" }, "recoveryCodeDesc": { "message": "Perdeu o acesso a todos os seus provedores de dois passos? Utilize o seu código de recuperação para desativar todos os provedores de dois passos da sua conta." @@ -1155,7 +1155,7 @@ "message": "Último nome" }, "fullName": { - "message": "Nome Completo" + "message": "Nome completo" }, "identityName": { "message": "Nome de identidade" @@ -1274,7 +1274,7 @@ "description": "Domain name. Ex. website.com" }, "domainName": { - "message": "Nome do Domínio", + "message": "Nome do domínio", "description": "Domain name. Ex. website.com" }, "host": { @@ -1863,7 +1863,7 @@ "message": "You must verify your email to use this feature. You can verify your email in the web vault." }, "updatedMasterPassword": { - "message": "Palavra-passe Mestra Atualizada" + "message": "Palavra-passe mestra atualizada" }, "updateMasterPassword": { "message": "Atualizar Senha Mestra" @@ -1977,10 +1977,10 @@ "message": "A sua sessão expirou. Por favor, volte atrás e tente iniciar sessão novamente." }, "exportingPersonalVaultTitle": { - "message": "A Exportar Cofre Pessoal" + "message": "A exportar cofre pessoal" }, "exportingPersonalVaultDescription": { - "message": "Apenas os itens do cofre pessoal associado ao $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos.", + "message": "Apenas os itens do cofre pessoal associado a $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos.", "placeholders": { "email": { "content": "$1", @@ -2017,16 +2017,16 @@ "message": "Aleatório" }, "randomWord": { - "message": "Palavra Aleatória" + "message": "Palavra aleatória" }, "websiteName": { - "message": "Nome do Site" + "message": "Nome do site" }, "whatWouldYouLikeToGenerate": { - "message": "O que desejaria de gerar?" + "message": "O que é que gostaria de gerar?" }, "passwordType": { - "message": "Tipo de Palavra-passe" + "message": "Tipo de palavra-passe" }, "service": { "message": "Serviço" @@ -2114,10 +2114,10 @@ "message": "Utilizador incorreto?" }, "newAroundHere": { - "message": "Novo por aqui?" + "message": "É novo por cá?" }, "rememberEmail": { - "message": "Relembrar e-mail" + "message": "Lembrar e-mail" }, "loginWithDevice": { "message": "Log in with device" diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 91fdc621fd..53c32c686c 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -11,7 +11,7 @@ "description": "Extension description" }, "loginOrCreateNewAccount": { - "message": "Prijavite se ali ustvarite nov račun za dostop do vašega varnega trezorja." + "message": "Prijavite se ali ustvarite nov račun za dostop do svojega varnega trezorja." }, "createAccount": { "message": "Ustvari račun" @@ -38,10 +38,10 @@ "message": "Glavno geslo" }, "masterPassDesc": { - "message": "Glavno geslo je geslo, ki ga uporabljate za dostop do vašega trezorja. Zelo pomembno je, da ne pozabite vaše glavno geslo. Gesla ni mogoče obnoviti v primeru, če ga pozabite." + "message": "Glavno geslo je geslo, ki ga uporabljate za dostop do svojega trezorja. Zelo pomembno je, da ga ne pozabite. Če pozabite glavno geslo, ga ne bo mogoče obnoviti." }, "masterPassHintDesc": { - "message": "Namig glavnega gesla vam lahko pomaga, da se spomnite vašega gesla, če ga pozabite." + "message": "Če pozabite glavno geslo, boste prejeli ta namig, da bi se gesla laže spomnili." }, "reTypeMasterPass": { "message": "Ponovno vnesite glavno geslo" @@ -678,13 +678,13 @@ "message": "Ta datoteka z izvoženimi podatki vsebuje podatke iz vašega trezorja v nešifrirani obliki. Ne shranjujte in ne pošiljajte je po nezavarovanih kanalih, kot je elektronska pošta. Po uporabi jo takoj izbrišite." }, "encExportKeyWarningDesc": { - "message": "Ta izvoz šifrira vaše podatke z uporabo ključa za šifriranje. Če boste kdaj zamenjali ključ za šifriranje, je potrebno, da ponovno naredite izvoz, ker ne boste mogli dešifrirati to izvoženo datoteko." + "message": "Ta izvoz šifrira vaše podatke z uporabo ključa za šifriranje. Če boste kdaj zamenjali ključ za šifriranje, boste morali podatke izvoziti ponovno, saj pričujočega izvoza ne boste mogli več dešifrirati." }, "encExportAccountWarningDesc": { "message": "Ključ za šifriranje je edinstven za vsak Bitwarden račun, zato ni mogoče da se uvozi šifrirana datoteka v drugi račun." }, "exportMasterPassword": { - "message": "Vnesite vaše glavno geslo za izvoz podatkov iz vašega trezorja." + "message": "Za izvoz podatkov iz trezorja vnesite svoje glavno geslo." }, "shared": { "message": "V skupni rabi" @@ -763,7 +763,7 @@ "message": "Funkcija ni na voljo." }, "updateKey": { - "message": "Ne morete koristiti to funkcijo dokler ne posodobite vaš ključ za šifriranje." + "message": "To funkcijo lahko uporabite šele, ko posodobite svoj šifrirni ključ." }, "premiumMembership": { "message": "Premium članstvo" @@ -841,7 +841,7 @@ "message": "Premium članstvo je potrebno za uporabo te funkcije." }, "enterVerificationCodeApp": { - "message": "Vnesite 6-mestno verifikacijsko kodo iz vaše verifikacijske aplikacije." + "message": "Vnesite 6-mestno verifikacijsko kodo iz svoje aplikacije za avtentikacijo." }, "enterVerificationCodeEmail": { "message": "Vnesite 6-mestno verifikacijsko kodo, ki vam je bila poslana na $EMAIL$.", @@ -898,7 +898,7 @@ "message": "Možnosti dvostopenjske prijave" }, "recoveryCodeDesc": { - "message": "Ste izgubili dostop do vseh vaših ponudnikov dvostopenjske prijave? Uporabite svojo kodo za obnovitev in tako onemogočite dvostopenjsko prijavo v svoj račun." + "message": "Ste izgubili dostop do vseh ponudnikov dvostopenjske prijave? Uporabite svojo kodo za obnovitev in tako onemogočite dvostopenjsko prijavo v svoj račun." }, "recoveryCodeTitle": { "message": "Koda za obnovitev" @@ -1050,7 +1050,7 @@ "description": "This describes a value that is 'linked' (tied) to another value." }, "popup2faCloseMessage": { - "message": "Če kliknete izven pojavnega okna, da preverite vašo epošto za vašo verifikacijsko kodo, bo to povročilo, da se je pojavno okno zapre. Želite odpreti to pojavno okno v novem oknu, tako, da se ne bo zaprlo?" + "message": "Če kliknete izven tega pojavnega okna, da bi preverili pošto, se to pojavno okno zaprlo. Želite odpreti to pojavno okno v novem oknu, da se ne bo zaprlo?" }, "popupU2fCloseMessage": { "message": "Ta spletni brskalnik ne more obdelati U2F zahteve v tem pojavnem oknu. Želite odpreti to pojavno okno v novem oknu, tako, da se lahko prijavite z U2F?" diff --git a/apps/browser/store/locales/pt_PT/copy.resx b/apps/browser/store/locales/pt_PT/copy.resx index 9fd0780a54..b010092866 100644 --- a/apps/browser/store/locales/pt_PT/copy.resx +++ b/apps/browser/store/locales/pt_PT/copy.resx @@ -167,7 +167,7 @@ Secure and share sensitive data within your Bitwarden Vault from any browser, mo O seu cofre é também convenientemente acessível a partir do menu de contexto de clique de lado direito do rato - Gira automaticamente palvras-passe fortes, aleatórias e seguras + Gera automaticamente palavras-passe fortes, aleatórias e seguras A sua informação é gerida com segurança utilizando encriptação AES-256 bits From 1638a1d6f58416db4596406e6af9548153d95b23 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 10:52:48 +0200 Subject: [PATCH 43/75] Autosync the updated translations (#5519) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/pt_PT/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index c68d9cff8f..a151ff0fa8 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden - Gestor de palavras-passe gratuito", + "message": "Bitwarden - Free Password Manager", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { From f7b372a0b068e89b724115a6036902b539b8a4ad Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Fri, 26 May 2023 15:58:06 +0200 Subject: [PATCH 44/75] [PM-2276] Upgrade Storybook to v7 (#5258) --- .github/whitelist-capital-letters.txt | 1 - .github/workflows/chromatic.yml | 5 + .storybook/main.js | 33 - .storybook/main.ts | 53 + .storybook/preview.js | 38 - .storybook/preview.tsx | 39 + .storybook/tsconfig.json | 1 + angular.json | 31 +- .../access-selector.stories.ts | 7 +- .../product-switcher.stories.ts | 65 +- .../shared/report-card/report-card.stories.ts | 14 +- .../shared/report-list/report-list.stories.ts | 14 +- .../vault-items/vault-items.stories.ts | 21 +- .../secrets-manager/layout/layout.stories.ts | 75 +- .../overview/onboarding.stories.ts | 26 +- .../secrets-manager/shared/header.stories.ts | 29 +- .../{in-forms.stories.mdx => in-forms.mdx} | 0 .../src/async-actions/in-forms.stories.ts | 26 +- .../{overview.stories.mdx => overview.mdx} | 0 ...{standalone.stories.mdx => standalone.mdx} | 0 .../src/async-actions/standalone.stories.ts | 39 +- libs/components/src/avatar/avatar.stories.ts | 55 +- .../src/badge-list/badge-list.stories.ts | 27 +- libs/components/src/badge/badge.stories.ts | 71 +- .../banner.mdx} | 18 +- libs/components/src/banner/banner.stories.ts | 50 +- .../src/breadcrumbs/breadcrumbs.stories.ts | 98 +- .../button.mdx} | 22 +- libs/components/src/button/button.stories.ts | 150 +- .../components/src/callout/callout.stories.ts | 50 +- .../src/checkbox/checkbox.stories.ts | 73 +- .../color-password.component.ts | 2 +- .../color-password/color-password.stories.ts | 62 +- .../src/dialog/dialog.service.stories.ts | 8 +- .../src/dialog/dialog/dialog.stories.ts | 208 +- ...ple-configurable-dialog.service.stories.ts | 8 +- .../dialog/simple-dialog.service.stories.ts | 8 +- .../simple-dialog/simple-dialog.stories.ts | 116 +- .../src/form-field/bit-validators.stories.ts | 20 +- .../src/form-field/error-summary.stories.ts | 53 +- .../src/form-field/form-field.stories.ts | 313 +- .../src/form-field/multi-select.stories.ts | 423 +- .../password-input-toggle.stories.ts | 83 +- libs/components/src/form/form.stories.ts | 129 +- .../src/icon-button/icon-button.stories.ts | 128 +- libs/components/src/icon/icon.stories.ts | 32 +- libs/components/src/index.ts | 1 + libs/components/src/input/index.ts | 1 + libs/components/src/link/link.stories.ts | 184 +- libs/components/src/menu/menu.stories.ts | 74 +- .../src/navigation/nav-group.stories.ts | 48 +- .../src/navigation/nav-item.stories.ts | 80 +- .../src/no-items/no-items.stories.ts | 44 +- .../src/progress/progress.stories.ts | 29 +- .../src/radio-button/radio-button.stories.ts | 122 +- libs/components/src/search/search.stories.ts | 20 +- libs/components/src/select/select.stories.ts | 40 +- .../{colors.stories.mdx => colors.mdx} | 6 +- .../{forms-docs.stories.mdx => forms.mdx} | 2 +- .../stories/{icons.stories.mdx => icons.mdx} | 4 +- .../{input-docs.stories.mdx => input.mdx} | 4 +- ...roduction.stories.mdx => introduction.mdx} | 6 +- .../src/stories/typography.stories.mdx | 59 - .../table.mdx} | 16 +- libs/components/src/table/table.stories.ts | 256 +- libs/components/src/tabs/tabs.stories.ts | 137 +- .../src/toggle-group/toggle-group.stories.ts | 54 +- libs/components/src/typography/typography.mdx | 67 + .../src/typography/typography.stories.ts | 102 +- libs/components/tailwind.config.js | 7 +- package-lock.json | 18634 ++++------------ package.json | 28 +- 72 files changed, 6340 insertions(+), 16409 deletions(-) delete mode 100644 .storybook/main.js create mode 100644 .storybook/main.ts delete mode 100644 .storybook/preview.js create mode 100644 .storybook/preview.tsx rename libs/components/src/async-actions/{in-forms.stories.mdx => in-forms.mdx} (100%) rename libs/components/src/async-actions/{overview.stories.mdx => overview.mdx} (100%) rename libs/components/src/async-actions/{standalone.stories.mdx => standalone.mdx} (100%) rename libs/components/src/{stories/banner-docs.stories.mdx => banner/banner.mdx} (82%) rename libs/components/src/{stories/button-docs.stories.mdx => button/button.mdx} (88%) create mode 100644 libs/components/src/input/index.ts rename libs/components/src/stories/{colors.stories.mdx => colors.mdx} (98%) rename libs/components/src/stories/{forms-docs.stories.mdx => forms.mdx} (97%) rename libs/components/src/stories/{icons.stories.mdx => icons.mdx} (99%) rename libs/components/src/stories/{input-docs.stories.mdx => input.mdx} (95%) rename libs/components/src/stories/{Introduction.stories.mdx => introduction.mdx} (99%) delete mode 100644 libs/components/src/stories/typography.stories.mdx rename libs/components/src/{stories/table-docs.stories.mdx => table/table.mdx} (96%) create mode 100644 libs/components/src/typography/typography.mdx diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index 9e585d170e..1fbed379d6 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -24,7 +24,6 @@ ./libs/angular/src/validators/notAllowedValueAsync.validator.ts ./libs/angular/src/services/theming/themeBuilder.ts ./libs/angular/src/interfaces/selectOptions.ts -./libs/components/src/stories/Introduction.stories.mdx ./libs/common/src/misc/nodeUtils.ts ./libs/common/src/misc/linkedFieldOption.decorator.ts ./libs/common/src/misc/serviceUtils.ts diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 453a19423a..212a80de74 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -31,12 +31,17 @@ jobs: - name: Install Node dependencies run: npm ci + + # Manual build the storybook to resolve a chromatic/storybook bug related to TurboSnap + - name: Build Storybook + run: npm run build-storybook:ci - name: Publish to Chromatic uses: chromaui/action@a89b674adf766dbde41ad9ea2b2b60b91188a0f0 with: token: ${{ secrets.GITHUB_TOKEN }} projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + storybookBuildDir: ./storybook-static exitOnceUploaded: true onlyChanged: true externals: "[\"libs/components/**/*.scss\", \"libs/components/tailwind.config*.js\"]" diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index 3db3964022..0000000000 --- a/.storybook/main.js +++ /dev/null @@ -1,33 +0,0 @@ -const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); - -module.exports = { - stories: [ - "../libs/components/src/**/*.stories.mdx", - "../libs/components/src/**/*.stories.@(js|jsx|ts|tsx)", - "../apps/web/src/**/*.stories.mdx", - "../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)", - "../bitwarden_license/bit-web/src/**/*.stories.mdx", - "../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)", - ], - addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@storybook/addon-a11y", - "storybook-addon-designs", - ], - framework: "@storybook/angular", - core: { - builder: "webpack5", - disableTelemetry: true, - }, - env: (config) => ({ - ...config, - FLAGS: JSON.stringify({ - secretsManager: true, - }), - }), - webpackFinal: async (config, { configType }) => { - config.resolve.plugins = [new TsconfigPathsPlugin()]; - return config; - }, -}; diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000000..a7f12f469b --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,53 @@ +import { StorybookConfig } from "@storybook/angular"; +import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin"; +import remarkGfm from "remark-gfm"; + +const config: StorybookConfig = { + stories: [ + "../libs/components/src/**/*.mdx", + "../libs/components/src/**/*.stories.@(js|jsx|ts|tsx)", + "../apps/web/src/**/*.mdx", + "../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)", + "../bitwarden_license/bit-web/src/**/*.mdx", + "../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)", + ], + addons: [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-a11y", + { + name: "@storybook/addon-docs", + options: { + mdxPluginOptions: { + mdxCompileOptions: { + remarkPlugins: [remarkGfm], + }, + }, + }, + }, + ], + framework: { + name: "@storybook/angular", + options: {}, + }, + core: { + disableTelemetry: true, + }, + env: (config) => ({ + ...config, + FLAGS: JSON.stringify({ + secretsManager: true, + }), + }), + webpackFinal: async (config, { configType }) => { + if (config.resolve) { + config.resolve.plugins = [new TsconfigPathsPlugin()] as any; + } + return config; + }, + docs: { + autodocs: true, + }, +}; + +export default config; diff --git a/.storybook/preview.js b/.storybook/preview.js deleted file mode 100644 index 754e8d2b88..0000000000 --- a/.storybook/preview.js +++ /dev/null @@ -1,38 +0,0 @@ -import { setCompodocJson } from "@storybook/addon-docs/angular"; -import { componentWrapperDecorator, addDecorator } from "@storybook/angular"; - -import docJson from "../documentation.json"; -setCompodocJson(docJson); - -export const parameters = { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, - options: { - storySort: { - order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"], - }, - }, - docs: { inlineStories: true }, -}; - -// ng-template is used to scope any template reference variables and isolate the previews -const decorator = componentWrapperDecorator( - (story) => ` - -
${story}
-
- -
${story}
-
- - - -` -); - -addDecorator(decorator); diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 0000000000..86ab6ab374 --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,39 @@ +import { setCompodocJson } from "@storybook/addon-docs/angular"; +import { componentWrapperDecorator } from "@storybook/angular"; +import type { Preview } from "@storybook/angular"; + +import docJson from "../documentation.json"; +setCompodocJson(docJson); + +const decorator = componentWrapperDecorator( + (story) => ` + +
${story}
+
+ +
${story}
+
+ + ` +); + +const preview: Preview = { + decorators: [decorator], + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + options: { + storySort: { + order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"], + }, + }, + docs: { source: { type: "dynamic", excludeDecorators: true } }, + }, +}; + +export default preview; diff --git a/.storybook/tsconfig.json b/.storybook/tsconfig.json index 397be6b000..113cc5bcde 100644 --- a/.storybook/tsconfig.json +++ b/.storybook/tsconfig.json @@ -7,6 +7,7 @@ "exclude": ["../src/test.setup.ts", "../apps/src/**/*.spec.ts", "../libs/**/*.spec.ts"], "files": [ "./typings.d.ts", + "./preview.tsx", "../libs/components/src/main.ts", "../libs/components/src/polyfills.ts" ] diff --git a/angular.json b/angular.json index a2b82cc64e..4b62c771cb 100644 --- a/angular.json +++ b/angular.json @@ -135,20 +135,25 @@ } }, "defaultConfiguration": "development" - } - } - }, - "storybook": { - "projectType": "application", - "root": "libs/components", - "sourceRoot": "libs/components/src", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", + }, + "storybook": { + "builder": "@storybook/angular:start-storybook", "options": { - "tsConfig": ".storybook/tsconfig.json", - "styles": ["libs/components/src/styles.scss", "libs/components/src/styles.css"], - "scripts": [] + "configDir": ".storybook", + "browserTarget": "components:build", + "compodoc": true, + "compodocArgs": ["-p", "./tsconfig.json", "-e", "json", "-d", "."], + "port": 6006 + } + }, + "build-storybook": { + "builder": "@storybook/angular:build-storybook", + "options": { + "configDir": ".storybook", + "browserTarget": "components:build", + "compodoc": true, + "compodocArgs": ["-e", "json", "-d", "."], + "outputDir": "storybook-static" } } } diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts index e503aad587..4fa8e43520 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts @@ -1,6 +1,7 @@ +import { importProvidersFrom } from "@angular/core"; import { FormBuilder, FormsModule, ReactiveFormsModule } from "@angular/forms"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { applicationConfig, Meta, moduleMetadata, Story } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { @@ -39,12 +40,14 @@ export default { FormsModule, TabsModule, TableModule, - PreloadedEnglishI18nModule, JslibModule, IconButtonModule, ], providers: [], }), + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), ], parameters: {}, argTypes: { 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 d9494b5eb2..82144afa72 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 @@ -1,6 +1,6 @@ -import { Component, Directive, Input } from "@angular/core"; +import { Component, Directive, Input, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { BehaviorSubject } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -49,36 +49,7 @@ export default { StoryLayoutComponent, StoryContentComponent, ], - imports: [ - JslibModule, - MenuModule, - IconButtonModule, - LinkModule, - RouterModule.forRoot( - [ - { - path: "", - component: StoryLayoutComponent, - children: [ - { - path: "", - redirectTo: "vault", - pathMatch: "full", - }, - { - path: "sm/:organizationId", - component: StoryContentComponent, - }, - { - path: "vault", - component: StoryContentComponent, - }, - ], - }, - ], - { useHash: true } - ), - ], + imports: [JslibModule, MenuModule, IconButtonModule, LinkModule, RouterModule], providers: [ { provide: OrganizationService, useClass: MockOrganizationService }, MockOrganizationService, @@ -93,6 +64,36 @@ export default { }, ], }), + applicationConfig({ + providers: [ + importProvidersFrom( + RouterModule.forRoot( + [ + { + path: "", + component: StoryLayoutComponent, + children: [ + { + path: "", + redirectTo: "vault", + pathMatch: "full", + }, + { + path: "sm/:organizationId", + component: StoryContentComponent, + }, + { + path: "vault", + component: StoryContentComponent, + }, + ], + }, + ], + { useHash: true } + ) + ), + ], + }), ], } as Meta; diff --git a/apps/web/src/app/reports/shared/report-card/report-card.stories.ts b/apps/web/src/app/reports/shared/report-card/report-card.stories.ts index 82c5c4e83b..f3dea693b3 100644 --- a/apps/web/src/app/reports/shared/report-card/report-card.stories.ts +++ b/apps/web/src/app/reports/shared/report-card/report-card.stories.ts @@ -1,5 +1,6 @@ +import { importProvidersFrom } from "@angular/core"; import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { BadgeModule, IconModule } from "@bitwarden/components"; @@ -15,15 +16,12 @@ export default { component: ReportCardComponent, decorators: [ moduleMetadata({ - imports: [ - JslibModule, - BadgeModule, - IconModule, - RouterTestingModule, - PreloadedEnglishI18nModule, - ], + imports: [JslibModule, BadgeModule, IconModule, RouterTestingModule], declarations: [PremiumBadgeComponent], }), + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), ], args: { title: "Exposed Passwords", diff --git a/apps/web/src/app/reports/shared/report-list/report-list.stories.ts b/apps/web/src/app/reports/shared/report-list/report-list.stories.ts index 7a092d99d6..b477792dd4 100644 --- a/apps/web/src/app/reports/shared/report-list/report-list.stories.ts +++ b/apps/web/src/app/reports/shared/report-list/report-list.stories.ts @@ -1,5 +1,6 @@ +import { importProvidersFrom } from "@angular/core"; import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { BadgeModule, IconModule } from "@bitwarden/components"; @@ -17,15 +18,12 @@ export default { component: ReportListComponent, decorators: [ moduleMetadata({ - imports: [ - JslibModule, - BadgeModule, - RouterTestingModule, - PreloadedEnglishI18nModule, - IconModule, - ], + imports: [JslibModule, BadgeModule, RouterTestingModule, IconModule], declarations: [PremiumBadgeComponent, ReportCardComponent], }), + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), ], args: { reports: Object.values(reports).map((report) => ({ diff --git a/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts b/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts index 28464289cf..2f40ad9ab4 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts +++ b/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts @@ -1,6 +1,6 @@ -import { Component } from "@angular/core"; +import { importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { applicationConfig, Meta, moduleMetadata, Story } from "@storybook/angular"; import { BehaviorSubject } from "rxjs"; import { AvatarUpdateService } from "@bitwarden/common/abstractions/account/avatar-update.service"; @@ -28,11 +28,6 @@ import { Unassigned } from "../../individual-vault/vault-filter/shared/models/ro import { VaultItemsComponent } from "./vault-items.component"; import { VaultItemsModule } from "./vault-items.module"; -@Component({ - template: "", -}) -class EmptyComponent {} - const organizations = [...new Array(3).keys()].map(createOrganization); const groups = [...Array(3).keys()].map(createGroupView); const collections = [...Array(5).keys()].map(createCollectionView); @@ -46,11 +41,7 @@ export default { component: VaultItemsComponent, decorators: [ moduleMetadata({ - imports: [ - VaultItemsModule, - PreloadedEnglishI18nModule, - RouterModule.forRoot([{ path: "**", component: EmptyComponent }], { useHash: true }), - ], + imports: [VaultItemsModule, RouterModule], providers: [ { provide: EnvironmentService, @@ -103,6 +94,12 @@ export default { }, ], }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot([], { useHash: true })), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], args: { disabled: false, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts b/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts index f3ae4f57c5..533f86a6e6 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts @@ -1,6 +1,6 @@ -import { Component } from "@angular/core"; +import { Component, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { BehaviorSubject } from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; @@ -28,43 +28,46 @@ export default { component: LayoutComponent, decorators: [ moduleMetadata({ - imports: [ - RouterModule.forRoot( - [ - { - path: "", - component: LayoutComponent, - children: [ - { - path: "", - redirectTo: "secrets", - pathMatch: "full", - }, - { - path: "secrets", - component: StoryContentComponent, - data: { - title: "secrets", - searchTitle: "searchSecrets", - }, - }, - { - outlet: "sidebar", - path: "", - component: NavigationComponent, - }, - ], - }, - ], - { useHash: true } - ), - LayoutModule, - IconModule, - PreloadedEnglishI18nModule, - ], + imports: [RouterModule, LayoutModule, IconModule], declarations: [StoryContentComponent], providers: [{ provide: OrganizationService, useClass: MockOrganizationService }], }), + applicationConfig({ + providers: [ + importProvidersFrom( + RouterModule.forRoot( + [ + { + path: "", + component: LayoutComponent, + children: [ + { + path: "", + redirectTo: "secrets", + pathMatch: "full", + }, + { + path: "secrets", + component: StoryContentComponent, + data: { + title: "secrets", + searchTitle: "searchSecrets", + }, + }, + { + outlet: "sidebar", + path: "", + component: NavigationComponent, + }, + ], + }, + ], + { useHash: true } + ) + ), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], } as Meta; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts b/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts index 73fc2738ec..a25e386307 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts @@ -1,5 +1,6 @@ +import { importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { delay, of, startWith } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -14,24 +15,15 @@ export default { component: OnboardingComponent, decorators: [ moduleMetadata({ - imports: [ - JslibModule, - RouterModule.forRoot( - [ - { - path: "", - component: OnboardingComponent, - }, - ], - { useHash: true } - ), - LinkModule, - IconModule, - ProgressModule, - PreloadedEnglishI18nModule, - ], + imports: [JslibModule, RouterModule, LinkModule, IconModule, ProgressModule], declarations: [OnboardingTaskComponent], }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot([], { useHash: true })), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], } as Meta; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts index 8ded21b956..508573d466 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts @@ -1,6 +1,12 @@ -import { Component, Injectable } from "@angular/core"; +import { Component, Injectable, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata, componentWrapperDecorator } from "@storybook/angular"; +import { + Meta, + Story, + moduleMetadata, + componentWrapperDecorator, + applicationConfig, +} from "@storybook/angular"; import { BehaviorSubject, combineLatest, map } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -16,8 +22,8 @@ import { NavigationModule, TabsModule, TypographyModule, + InputModule, } from "@bitwarden/components"; -import { InputModule } from "@bitwarden/components/src/input/input.module"; import { PreloadedEnglishI18nModule } from "@bitwarden/web-vault/app/tests/preloaded-english-i18n.module"; import { HeaderComponent } from "./header.component"; @@ -68,15 +74,7 @@ export default { moduleMetadata({ imports: [ JslibModule, - RouterModule.forRoot( - [ - { - path: "", - component: HeaderComponent, - }, - ], - { useHash: true } - ), + RouterModule, AvatarModule, BreadcrumbsModule, ButtonModule, @@ -87,7 +85,6 @@ export default { TabsModule, TypographyModule, NavigationModule, - PreloadedEnglishI18nModule, ], declarations: [HeaderComponent, MockProductSwitcher, MockDynamicAvatar], providers: [ @@ -100,6 +97,12 @@ export default { }, ], }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot([], { useHash: true })), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], } as Meta; diff --git a/libs/components/src/async-actions/in-forms.stories.mdx b/libs/components/src/async-actions/in-forms.mdx similarity index 100% rename from libs/components/src/async-actions/in-forms.stories.mdx rename to libs/components/src/async-actions/in-forms.mdx diff --git a/libs/components/src/async-actions/in-forms.stories.ts b/libs/components/src/async-actions/in-forms.stories.ts index ef789dc106..f72f1b6479 100644 --- a/libs/components/src/async-actions/in-forms.stories.ts +++ b/libs/components/src/async-actions/in-forms.stories.ts @@ -1,7 +1,7 @@ import { Component } from "@angular/core"; import { FormsModule, ReactiveFormsModule, Validators, FormBuilder } from "@angular/forms"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; import { delay, of } from "rxjs"; import { ValidationService } from "@bitwarden/common/abstractions/validation.service"; @@ -145,16 +145,18 @@ export default { ], } as Meta; -const PromiseTemplate: Story = (args: PromiseExampleComponent) => ({ - props: args, - template: ``, -}); +type Story = StoryObj; -export const UsingPromise = PromiseTemplate.bind({}); +export const UsingPromise: Story = { + render: (args) => ({ + props: args, + template: ``, + }), +}; -const ObservableTemplate: Story = (args: PromiseExampleComponent) => ({ - props: args, - template: ``, -}); - -export const UsingObservable = ObservableTemplate.bind({}); +export const UsingObservable: Story = { + render: (args) => ({ + props: args, + template: ``, + }), +}; diff --git a/libs/components/src/async-actions/overview.stories.mdx b/libs/components/src/async-actions/overview.mdx similarity index 100% rename from libs/components/src/async-actions/overview.stories.mdx rename to libs/components/src/async-actions/overview.mdx diff --git a/libs/components/src/async-actions/standalone.stories.mdx b/libs/components/src/async-actions/standalone.mdx similarity index 100% rename from libs/components/src/async-actions/standalone.stories.mdx rename to libs/components/src/async-actions/standalone.mdx diff --git a/libs/components/src/async-actions/standalone.stories.ts b/libs/components/src/async-actions/standalone.stories.ts index 5a8edfaaac..e4dec780e0 100644 --- a/libs/components/src/async-actions/standalone.stories.ts +++ b/libs/components/src/async-actions/standalone.stories.ts @@ -1,6 +1,6 @@ import { Component } from "@angular/core"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { delay, of } from "rxjs"; import { LogService } from "@bitwarden/common/abstractions/log.service"; @@ -80,25 +80,24 @@ export default { ], } as Meta; -const PromiseTemplate: Story = (args: PromiseExampleComponent) => ({ - props: args, - template: ``, -}); +type PromiseStory = StoryObj; +type ObservableStory = StoryObj; -export const UsingPromise = PromiseTemplate.bind({}); +export const UsingPromise: PromiseStory = { + render: (args) => ({ + props: args, + template: ``, + }), +}; -const ObservableTemplate: Story = ( - args: ObservableExampleComponent -) => ({ - template: ``, -}); +export const UsingObservable: ObservableStory = { + render: (args) => ({ + template: ``, + }), +}; -export const UsingObservable = ObservableTemplate.bind({}); - -const RejectedPromiseTemplate: Story = ( - args: ObservableExampleComponent -) => ({ - template: ``, -}); - -export const RejectedPromise = RejectedPromiseTemplate.bind({}); +export const RejectedPromise: ObservableStory = { + render: (args) => ({ + template: ``, + }), +}; diff --git a/libs/components/src/avatar/avatar.stories.ts b/libs/components/src/avatar/avatar.stories.ts index 724dc5ec0e..d3a00fbe34 100644 --- a/libs/components/src/avatar/avatar.stories.ts +++ b/libs/components/src/avatar/avatar.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { AvatarComponent } from "./avatar.component"; @@ -18,41 +18,46 @@ export default { }, } as Meta; -const Template: Story = (args: AvatarComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = { - color: "#175ddc", +export const Default: Story = { + args: { + color: "#175ddc", + }, }; -export const Large = Template.bind({}); -Large.args = { - size: "large", +export const Large: Story = { + args: { + size: "large", + }, }; -export const Small = Template.bind({}); -Small.args = { - size: "small", +export const Small: Story = { + args: { + size: "small", + }, }; -export const LightBackground = Template.bind({}); -LightBackground.args = { - color: "#d2ffcf", +export const LightBackground: Story = { + args: { + color: "#d2ffcf", + }, }; -export const Border = Template.bind({}); -Border.args = { - border: true, +export const Border: Story = { + args: { + border: true, + }, }; -export const ColorByID = Template.bind({}); -ColorByID.args = { - id: 236478, +export const ColorByID: Story = { + args: { + id: "236478", + }, }; -export const ColorByText = Template.bind({}); -ColorByText.args = { - text: "Jason Doe", +export const ColorByText: Story = { + args: { + text: "Jason Doe", + }, }; diff --git a/libs/components/src/badge-list/badge-list.stories.ts b/libs/components/src/badge-list/badge-list.stories.ts index 91214d8317..4e580badb1 100644 --- a/libs/components/src/badge-list/badge-list.stories.ts +++ b/libs/components/src/badge-list/badge-list.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -38,16 +38,19 @@ export default { }, } as Meta; -const ListTemplate: Story = (args: BadgeListComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -export const Default = ListTemplate.bind({}); -Default.args = { - badgeType: "info", - maxItems: 3, - items: ["Badge 1", "Badge 2", "Badge 3", "Badge 4", "Badge 5"], +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), + + args: { + badgeType: "info", + maxItems: 3, + items: ["Badge 1", "Badge 2", "Badge 3", "Badge 4", "Badge 5"], + }, }; diff --git a/libs/components/src/badge/badge.stories.ts b/libs/components/src/badge/badge.stories.ts index a5584c1a89..2efe5450d0 100644 --- a/libs/components/src/badge/badge.stories.ts +++ b/libs/components/src/badge/badge.stories.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; import { BadgeDirective } from "./badge.directive"; @@ -21,43 +21,54 @@ export default { url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=1881%3A16956", }, }, -} as Meta; +} as Meta; -const Template: Story = (args: BadgeDirective) => ({ - props: args, - template: ` - Span Badge -

- Link Badge -

- Button - `, -}); +type Story = StoryObj; -export const Primary = Template.bind({}); -Primary.args = {}; - -export const Secondary = Template.bind({}); -Secondary.args = { - badgeType: "secondary", +export const Primary: Story = { + render: (args) => ({ + props: args, + template: ` + Span Badge +

+ Link Badge +

+ Button + `, + }), }; -export const Success = Template.bind({}); -Success.args = { - badgeType: "success", +export const Secondary: Story = { + ...Primary, + args: { + badgeType: "secondary", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - badgeType: "danger", +export const Success: Story = { + ...Primary, + args: { + badgeType: "success", + }, }; -export const Warning = Template.bind({}); -Warning.args = { - badgeType: "warning", +export const Danger: Story = { + ...Primary, + args: { + badgeType: "danger", + }, }; -export const Info = Template.bind({}); -Info.args = { - badgeType: "info", +export const Warning: Story = { + ...Primary, + args: { + badgeType: "warning", + }, +}; + +export const Info: Story = { + ...Primary, + args: { + badgeType: "info", + }, }; diff --git a/libs/components/src/stories/banner-docs.stories.mdx b/libs/components/src/banner/banner.mdx similarity index 82% rename from libs/components/src/stories/banner-docs.stories.mdx rename to libs/components/src/banner/banner.mdx index 61b216523b..84c71cde95 100644 --- a/libs/components/src/stories/banner-docs.stories.mdx +++ b/libs/components/src/banner/banner.mdx @@ -1,6 +1,8 @@ -import { Meta, Story } from "@storybook/addon-docs"; +import { Meta, Story, Controls, Canvas, Primary } from "@storybook/addon-docs"; - +import * as stories from "./banner.stories"; + + # Banner @@ -15,6 +17,10 @@ persist across all pages a user navigates to. - Avoid stacking multiple banners. - Banners support a button link (text button). + + + + ## Types Icons should remain consistent across these types. Do not change the icon without consulting @@ -24,25 +30,25 @@ Use the following guidelines to help choose the correct type of banner. ### Premium - + Used primarily to encourage user to upgrade to premium. ### Info - + Used to communicate release notes, server maintenance or other informative event. ### Warning - + Used to alert the user of outdated info or versions. ### Danger - + Rarely used, but may be used to alert users over critical messages or very outdated versions. diff --git a/libs/components/src/banner/banner.stories.ts b/libs/components/src/banner/banner.stories.ts index e636124fe0..e2c8a0c82b 100644 --- a/libs/components/src/banner/banner.stories.ts +++ b/libs/components/src/banner/banner.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -39,34 +39,46 @@ export default { argTypes: { onClose: { action: "onClose" }, }, -} as Meta; +} as Meta; -const Template: Story = (args: BannerComponent) => ({ - props: args, - template: ` - +type Story = StoryObj; + +export const Premium: Story = { + args: { + bannerType: "premium", + }, + render: (args: BannerComponent) => ({ + props: args, + template: ` + Content Really Long Text Lorem Ipsum Ipsum Ipsum - - `, -}); + + `, + }), +}; -export const Premium = Template.bind({}); Premium.args = { bannerType: "premium", }; -export const Info = Template.bind({}); -Info.args = { - bannerType: "info", +export const Info: Story = { + ...Premium, + args: { + bannerType: "info", + }, }; -export const Warning = Template.bind({}); -Warning.args = { - bannerType: "warning", +export const Warning: Story = { + ...Premium, + args: { + bannerType: "warning", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - bannerType: "danger", +export const Danger: Story = { + ...Premium, + args: { + bannerType: "danger", + }, }; diff --git a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts index 782bb39e75..673b702727 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts @@ -1,6 +1,6 @@ -import { Component } from "@angular/core"; +import { Component, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; import { IconButtonModule } from "../icon-button"; import { LinkModule } from "../link"; @@ -26,16 +26,19 @@ export default { decorators: [ moduleMetadata({ declarations: [BreadcrumbComponent], - imports: [ - LinkModule, - MenuModule, - IconButtonModule, - RouterModule.forRoot([{ path: "**", component: EmptyComponent }], { useHash: true }), + imports: [LinkModule, MenuModule, IconButtonModule, RouterModule], + }), + applicationConfig({ + providers: [ + importProvidersFrom( + RouterModule.forRoot([{ path: "**", component: EmptyComponent }], { useHash: true }) + ), ], }), ], args: { items: [], + show: 3, }, argTypes: { breadcrumbs: { @@ -45,47 +48,54 @@ export default { }, } as Meta; -const Template: Story = (args: BreadcrumbsComponent) => ({ - props: args, - template: ` -

Router links

-

- - {{item.name}} - -

+type Story = StoryObj; -

Click emit

-

- - {{item.name}} - -

- `, -}); +export const TopLevel: Story = { + render: (args) => ({ + props: args, + template: ` +

Router links

+

+ + {{item.name}} + +

+ +

Click emit

+

+ + {{item.name}} + +

+ `, + }), -export const TopLevel = Template.bind({}); -TopLevel.args = { - items: [{ icon: "bwi-star", name: "Top Level" }] as Breadcrumb[], + args: { + items: [{ icon: "bwi-star", name: "Top Level" }] as Breadcrumb[], + }, }; -export const SecondLevel = Template.bind({}); -SecondLevel.args = { - items: [ - { name: "Acme Vault", route: "/" }, - { icon: "bwi-collection", name: "Collection", route: "collection" }, - ] as Breadcrumb[], +export const SecondLevel: Story = { + ...TopLevel, + args: { + items: [ + { name: "Acme Vault", route: "/" }, + { icon: "bwi-collection", name: "Collection", route: "collection" }, + ] as Breadcrumb[], + }, }; -export const Overflow = Template.bind({}); -Overflow.args = { - items: [ - { name: "Acme Vault", route: "" }, - { icon: "bwi-collection", name: "Collection", route: "collection" }, - { icon: "bwi-collection", name: "Middle-Collection 1", route: "middle-collection-1" }, - { icon: "bwi-collection", name: "Middle-Collection 2", route: "middle-collection-2" }, - { icon: "bwi-collection", name: "Middle-Collection 3", route: "middle-collection-3" }, - { icon: "bwi-collection", name: "Middle-Collection 4", route: "middle-collection-4" }, - { icon: "bwi-collection", name: "End Collection", route: "end-collection" }, - ] as Breadcrumb[], +export const Overflow: Story = { + ...TopLevel, + args: { + items: [ + { name: "Acme Vault", route: "" }, + { icon: "bwi-collection", name: "Collection", route: "collection" }, + { icon: "bwi-collection", name: "Middle-Collection 1", route: "middle-collection-1" }, + { icon: "bwi-collection", name: "Middle-Collection 2", route: "middle-collection-2" }, + { icon: "bwi-collection", name: "Middle-Collection 3", route: "middle-collection-3" }, + { icon: "bwi-collection", name: "Middle-Collection 4", route: "middle-collection-4" }, + { icon: "bwi-collection", name: "End Collection", route: "end-collection" }, + ] as Breadcrumb[], + }, }; diff --git a/libs/components/src/stories/button-docs.stories.mdx b/libs/components/src/button/button.mdx similarity index 88% rename from libs/components/src/stories/button-docs.stories.mdx rename to libs/components/src/button/button.mdx index 3551be8cf6..fddbda36fb 100644 --- a/libs/components/src/stories/button-docs.stories.mdx +++ b/libs/components/src/button/button.mdx @@ -1,12 +1,18 @@ -import { Meta, Story } from "@storybook/addon-docs"; +import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; - +import * as stories from "./button.stories"; + + # Button Buttons are interactive elements that can be triggered using a mouse, keyboard, or touch. They are used to indicate actions that can be performed by a user such as submitting a form. + + + + ## Guidelines ### Choosing the `` or ` - Link - `, -}); +type Story = StoryObj; -export const Primary = Template.bind({}); -Primary.args = { - buttonType: "primary", +export const Primary: Story = { + render: (args) => ({ + props: args, + template: ` + + Link + `, + }), + args: { + buttonType: "primary", + }, }; -export const Secondary = Template.bind({}); -Secondary.args = { - buttonType: "secondary", +export const Secondary: Story = { + ...Primary, + args: { + buttonType: "secondary", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - buttonType: "danger", +export const Danger: Story = { + ...Primary, + args: { + buttonType: "danger", + }, }; -const AllStylesTemplate: Story = (args) => ({ - props: args, - template: ` - - - - `, -}); - -export const Loading = AllStylesTemplate.bind({}); -Loading.args = { - disabled: false, - loading: true, +export const Loading: Story = { + render: (args) => ({ + props: args, + template: ` + + + + `, + }), + args: { + disabled: false, + loading: true, + }, }; -export const Disabled = AllStylesTemplate.bind({}); -Disabled.args = { - disabled: true, - loading: false, +export const Disabled: Story = { + ...Loading, + args: { + disabled: true, + loading: false, + }, }; -const DisabledWithAttributeTemplate: Story = (args) => ({ - props: args, - template: ` - - - - - - - - - - - `, -}); - -export const DisabledWithAttribute = DisabledWithAttributeTemplate.bind({}); -DisabledWithAttribute.args = { - disabled: true, - loading: false, +export const DisabledWithAttribute: Story = { + render: (args) => ({ + props: args, + template: ` + + + + + + + + + + + `, + }), + args: { + disabled: true, + loading: false, + }, }; -const BlockTemplate: Story = (args: ButtonComponent) => ({ - props: args, - template: ` - - - [block]="true" Link - - - block Link - - `, -}); - -export const Block = BlockTemplate.bind({}); -Block.args = { - block: true, +export const Block: Story = { + render: (args: ButtonComponent) => ({ + props: args, + template: ` + + + [block]="true" Link + + + block Link + + `, + }), + args: { + block: true, + }, }; diff --git a/libs/components/src/callout/callout.stories.ts b/libs/components/src/callout/callout.stories.ts index 89469a6f64..f8738e46b3 100644 --- a/libs/components/src/callout/callout.stories.ts +++ b/libs/components/src/callout/callout.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -35,31 +35,39 @@ export default { }, } as Meta; -const Template: Story = (args: CalloutComponent) => ({ - props: args, - template: ` - Content - `, -}); +type Story = StoryObj; -export const Success = Template.bind({}); -Success.args = { - type: "success", - title: "Success", +export const Success: Story = { + render: (args) => ({ + props: args, + template: ` + Content + `, + }), + args: { + type: "success", + title: "Success", + }, }; -export const Info = Template.bind({}); -Info.args = { - type: "info", - title: "Info", +export const Info: Story = { + ...Success, + args: { + type: "info", + title: "Info", + }, }; -export const Warning = Template.bind({}); -Warning.args = { - type: "warning", +export const Warning: Story = { + ...Success, + args: { + type: "warning", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - type: "danger", +export const Danger: Story = { + ...Success, + args: { + type: "danger", + }, }; diff --git a/libs/components/src/checkbox/checkbox.stories.ts b/libs/components/src/checkbox/checkbox.stories.ts index a384dd2ce0..246e4ada7b 100644 --- a/libs/components/src/checkbox/checkbox.stories.ts +++ b/libs/components/src/checkbox/checkbox.stories.ts @@ -1,6 +1,6 @@ import { Component, Input } from "@angular/core"; import { FormsModule, ReactiveFormsModule, FormBuilder, Validators } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/src/abstractions/i18n.service"; @@ -69,43 +69,44 @@ export default { }, } as Meta; -const DefaultTemplate: Story = (args: ExampleComponent) => ({ - props: args, - template: ``, -}); +type Story = StoryObj; -export const Default = DefaultTemplate.bind({}); -Default.parameters = { - docs: { - source: { - code: template, +export const Default: Story = { + render: (args) => ({ + props: args, + template: ``, + }), + parameters: { + docs: { + source: { + code: template, + }, }, }, -}; -Default.args = { - checked: false, - disabled: false, + args: { + checked: false, + disabled: false, + }, }; -const CustomTemplate: Story = (args) => ({ - props: args, - template: ` -
- - - -
- `, -}); -CustomTemplate.args = {}; - -export const Custom = CustomTemplate.bind({}); +export const Custom: Story = { + render: (args) => ({ + props: args, + template: ` +
+ + + +
+ `, + }), +}; diff --git a/libs/components/src/color-password/color-password.component.ts b/libs/components/src/color-password/color-password.component.ts index 14b825df71..04172bfa87 100644 --- a/libs/components/src/color-password/color-password.component.ts +++ b/libs/components/src/color-password/color-password.component.ts @@ -23,7 +23,7 @@ enum CharacterType { preserveWhitespaces: false, }) export class ColorPasswordComponent { - @Input() private password: string = null; + @Input() password: string = null; @Input() showCount = false; characterStyles: Record = { diff --git a/libs/components/src/color-password/color-password.stories.ts b/libs/components/src/color-password/color-password.stories.ts index cba57132bb..07418cad72 100644 --- a/libs/components/src/color-password/color-password.stories.ts +++ b/libs/components/src/color-password/color-password.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { ColorPasswordComponent } from "./color-password.component"; @@ -19,34 +19,40 @@ export default { }, } as Meta; -const Template: Story = (args: ColorPasswordComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -const WrappedTemplate: Story = (args: ColorPasswordComponent) => ({ - props: args, - template: ` -
- -
- `, -}); - -export const ColorPassword = Template.bind({}); - -export const WrappedColorPassword = WrappedTemplate.bind({}); - -export const ColorPasswordCount = Template.bind({}); -ColorPasswordCount.args = { - password: examplePassword, - showCount: true, +export const ColorPassword: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), }; -export const WrappedColorPasswordCount = WrappedTemplate.bind({}); -WrappedColorPasswordCount.args = { - password: examplePassword, - showCount: true, +export const WrappedColorPassword: Story = { + render: (args) => ({ + props: args, + template: ` +
+ +
+ `, + }), +}; + +export const ColorPasswordCount: Story = { + ...ColorPassword, + args: { + password: examplePassword, + showCount: true, + }, +}; + +export const WrappedColorPasswordCount: Story = { + ...WrappedColorPassword, + args: { + password: examplePassword, + showCount: true, + }, }; diff --git a/libs/components/src/dialog/dialog.service.stories.ts b/libs/components/src/dialog/dialog.service.stories.ts index 5699c04abd..c189b28bc2 100644 --- a/libs/components/src/dialog/dialog.service.stories.ts +++ b/libs/components/src/dialog/dialog.service.stories.ts @@ -1,6 +1,6 @@ import { DIALOG_DATA, DialogModule, DialogRef } from "@angular/cdk/dialog"; import { Component, Inject } from "@angular/core"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -90,8 +90,6 @@ export default { }, } as Meta; -const Template: Story = (args: StoryDialogComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = {}; diff --git a/libs/components/src/dialog/dialog/dialog.stories.ts b/libs/components/src/dialog/dialog/dialog.stories.ts index 6e01462013..ce9dedc128 100644 --- a/libs/components/src/dialog/dialog/dialog.stories.ts +++ b/libs/components/src/dialog/dialog/dialog.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -50,110 +50,118 @@ export default { }, } as Meta; -const Template: Story = (args: DialogComponent) => ({ - props: args, - template: ` - - {{title}} - Dialog body text goes here. - - - - - - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = { - dialogSize: "default", - title: "Default", -}; - -export const Small = Template.bind({}); -Small.args = { - dialogSize: "small", - title: "Small", -}; - -export const LongTitle = Template.bind({}); -LongTitle.args = { - dialogSize: "small", - title: "Long_Title_That_Should_Be_Truncated", -}; - -export const Large = Template.bind({}); -Large.args = { - dialogSize: "large", - title: "Large", -}; - -export const Loading = Template.bind({}); -Loading.args = { - dialogSize: "large", - loading: true, - title: "Loading", -}; - -const TemplateScrolling: Story = (args: DialogComponent) => ({ - props: args, - template: ` - - Scrolling Example - - Dialog body text goes here.
- - repeating lines of characters
+export const Default: Story = { + render: (args: DialogComponent) => ({ + props: args, + template: ` + + {{title}} + Dialog body text goes here. + + + + - end of sequence! -
- - - - -
- `, -}); - -export const ScrollingContent = TemplateScrolling.bind({}); -ScrollingContent.args = { - dialogSize: "small", + + `, + }), + args: { + dialogSize: "default", + title: "Default", + }, }; -const TemplateTabbed: Story = (args: DialogComponent) => ({ - props: args, - template: ` - - Tab Content Example - - - First Tab Content - Second Tab Content - Third Tab Content - - - - - - - - `, -}); - -export const TabContent = TemplateTabbed.bind({}); -TabContent.args = { - dialogSize: "large", - disablePadding: true, +export const Small: Story = { + ...Default, + args: { + dialogSize: "small", + title: "Small", + }, }; -TabContent.story = { + +export const LongTitle: Story = { + ...Default, + args: { + dialogSize: "small", + title: "Long_Title_That_Should_Be_Truncated", + }, +}; + +export const Large: Story = { + ...Default, + args: { + dialogSize: "large", + title: "Large", + }, +}; + +export const Loading: Story = { + ...Default, + args: { + dialogSize: "large", + loading: true, + title: "Loading", + }, +}; + +export const ScrollingContent: Story = { + render: (args: DialogComponent) => ({ + props: args, + template: ` + + Scrolling Example + + Dialog body text goes here.
+ + repeating lines of characters
+
+ end of sequence! +
+ + + + +
+ `, + }), + args: { + dialogSize: "small", + }, +}; + +export const TabContent: Story = { + render: (args) => ({ + props: args, + template: ` + + Tab Content Example + + + First Tab Content + Second Tab Content + Third Tab Content + + + + + + + + `, + }), + args: { + dialogSize: "large", + disablePadding: true, + }, parameters: { docs: { storyDescription: `An example of using the \`bitTabGroup\` component within the Dialog. The content padding should be diff --git a/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts b/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts index 27c66538a0..f8910fdb8f 100644 --- a/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts @@ -1,6 +1,6 @@ import { DialogModule } from "@angular/cdk/dialog"; import { Component } from "@angular/core"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { SimpleDialogType, SimpleDialogOptions } from "@bitwarden/angular/services/dialog"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -239,8 +239,6 @@ export default { }, } as Meta; -const Template: Story = (args: StoryDialogComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = {}; diff --git a/libs/components/src/dialog/simple-dialog.service.stories.ts b/libs/components/src/dialog/simple-dialog.service.stories.ts index cab7270576..e4d60c96de 100644 --- a/libs/components/src/dialog/simple-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-dialog.service.stories.ts @@ -1,6 +1,6 @@ import { DialogModule, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; import { Component, Inject } from "@angular/core"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -90,8 +90,6 @@ export default { }, } as Meta; -const Template: Story = (args: StoryDialogComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = {}; diff --git a/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts b/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts index 1e5514abe5..27a82c4610 100644 --- a/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts +++ b/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { ButtonModule } from "../../button"; import { DialogTitleContainerDirective } from "../directives/dialog-title-container.directive"; @@ -22,61 +22,63 @@ export default { }, } as Meta; -const Template: Story = (args: SimpleDialogComponent) => ({ - props: args, - template: ` - - Alert Dialog - Message Content - - - - - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); - -const TemplateWithIcon: Story = (args: SimpleDialogComponent) => ({ - props: args, - template: ` - - - Premium Subscription Available - Message Content - - - - - - `, -}); - -export const CustomIcon = TemplateWithIcon.bind({}); - -const TemplateScroll: Story = (args: SimpleDialogComponent) => ({ - props: args, - template: ` - - Alert Dialog - - Message Content - Message text goes here.
- - repeating lines of characters
-
- end of sequence! -
- - - - -
- `, -}); - -export const ScrollingContent = TemplateScroll.bind({}); -ScrollingContent.args = { - useDefaultIcon: true, +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + Alert Dialog + Message Content + + + + + + `, + }), +}; + +export const CustomIcon: Story = { + render: (args) => ({ + props: args, + template: ` + + + Premium Subscription Available + Message Content + + + + + + `, + }), +}; + +export const ScrollingContent: Story = { + render: (args: SimpleDialogComponent) => ({ + props: args, + template: ` + + Alert Dialog + + Message Content + Message text goes here.
+ + repeating lines of characters
+
+ end of sequence! +
+ + + + +
+ `, + }), + args: { + useDefaultIcon: true, + }, }; diff --git a/libs/components/src/form-field/bit-validators.stories.ts b/libs/components/src/form-field/bit-validators.stories.ts index e12b13dd40..9e717a3510 100644 --- a/libs/components/src/form-field/bit-validators.stories.ts +++ b/libs/components/src/form-field/bit-validators.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule, FormBuilder } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { StoryObj, Meta, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -46,11 +46,13 @@ const template = ` `; -export const ForbiddenCharacters: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: new FormBuilder().group({ - name: ["", forbiddenCharacters(["\\", "/", "@", "#", "$", "%", "^", "&", "*", "(", ")"])], - }), - }, - template, -}); +export const ForbiddenCharacters: StoryObj = { + render: (args: BitFormFieldComponent) => ({ + props: { + formObj: new FormBuilder().group({ + name: ["", forbiddenCharacters(["\\", "/", "@", "#", "$", "%", "^", "&", "*", "(", ")"])], + }), + }, + template, + }), +}; diff --git a/libs/components/src/form-field/error-summary.stories.ts b/libs/components/src/form-field/error-summary.stories.ts index f85e579002..16bfd99ac4 100644 --- a/libs/components/src/form-field/error-summary.stories.ts +++ b/libs/components/src/form-field/error-summary.stories.ts @@ -1,5 +1,5 @@ import { UntypedFormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -50,29 +50,28 @@ function submit() { formObj.markAllAsTouched(); } -const Template: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: formObj, - submit: submit, - ...args, - }, - template: ` -
- - Name - - - - - Email - - - - - -
- `, -}); - -export const Default = Template.bind({}); -Default.props = {}; +export const Default: StoryObj = { + render: (args) => ({ + props: { + formObj: formObj, + submit: submit, + ...args, + }, + template: ` +
+ + Name + + + + + Email + + + + + +
+ `, + }), +}; diff --git a/libs/components/src/form-field/form-field.stories.ts b/libs/components/src/form-field/form-field.stories.ts index 1b46e6e6c5..c8c520bb81 100644 --- a/libs/components/src/form-field/form-field.stories.ts +++ b/libs/components/src/form-field/form-field.stories.ts @@ -7,7 +7,7 @@ import { ValidatorFn, Validators, } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -87,173 +87,168 @@ function forbiddenNameValidator(nameRe: RegExp): ValidatorFn { function submit() { defaultFormObj.markAllAsTouched(); } +type Story = StoryObj; -const Template: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: defaultFormObj, - submit: submit, - ...args, - }, - template: ` -
+export const Default: Story = { + render: (args) => ({ + props: { + formObj: defaultFormObj, + submit: submit, + ...args, + }, + template: ` + + + Label + + Optional Hint + +
+ `, + }), +}; + +export const Required: Story = { + render: (args) => ({ + props: { + formObj: formObj, + ...args, + }, + template: ` Label - - Optional Hint + - - `, -}); + + + FormControl + + + `, + }), +}; -export const Default = Template.bind({}); -Default.props = {}; +export const Hint: Story = { + render: (args: BitFormFieldComponent) => ({ + props: { + formObj: formObj, + ...args, + }, + template: ` + + FormControl + + Long hint text + + `, + }), +}; -const RequiredTemplate: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: formObj, - ...args, - }, - template: ` - - Label - - +export const Disabled: Story = { + render: (args) => ({ + props: args, + template: ` + + Label + + + `, + }), + args: {}, +}; - - FormControl - - - `, -}); +export const InputGroup: Story = { + render: (args) => ({ + props: args, + template: ` + + Label + + $ + USD + + `, + }), + args: {}, +}; -export const Required = RequiredTemplate.bind({}); -Required.props = {}; +export const ButtonInputGroup: Story = { + render: (args) => ({ + props: args, + template: ` + + + + + + + + `, + }), + args: {}, +}; -const HintTemplate: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: formObj, - ...args, - }, - template: ` - - FormControl - - Long hint text - - `, -}); +export const DisabledButtonInputGroup: Story = { + render: (args) => ({ + props: args, + template: ` + + Label + + + + + + + `, + }), + args: {}, +}; -export const Hint = HintTemplate.bind({}); -Required.props = {}; +export const Select: Story = { + render: (args: BitFormFieldComponent) => ({ + props: args, + template: ` + + Label + + + `, + }), + args: {}, +}; -const DisabledTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - - `, -}); +export const AdvancedSelect: Story = { + render: (args: BitFormFieldComponent) => ({ + props: args, + template: ` + + Label + + + + + + `, + }), +}; -export const Disabled = DisabledTemplate.bind({}); -Disabled.args = {}; - -const GroupTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - $ - USD - - `, -}); - -export const InputGroup = GroupTemplate.bind({}); -InputGroup.args = {}; - -const ButtonGroupTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - - - - - - - `, -}); - -export const ButtonInputGroup = ButtonGroupTemplate.bind({}); -ButtonInputGroup.args = {}; - -const DisabledButtonInputGroupTemplate: Story = ( - args: BitFormFieldComponent -) => ({ - props: args, - template: ` - - Label - - - - - - - `, -}); - -export const DisabledButtonInputGroup = DisabledButtonInputGroupTemplate.bind({}); -DisabledButtonInputGroup.args = {}; - -const SelectTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - - `, -}); - -export const Select = SelectTemplate.bind({}); -Select.args = {}; - -const AdvancedSelectTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - - - - - `, -}); - -export const AdvancedSelect = AdvancedSelectTemplate.bind({}); -AdvancedSelectTemplate.args = {}; - -const TextareaTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Textarea - - - `, -}); - -export const Textarea = TextareaTemplate.bind({}); -Textarea.args = {}; +export const Textarea: Story = { + render: (args: BitFormFieldComponent) => ({ + props: args, + template: ` + + Textarea + + + `, + }), + args: {}, +}; diff --git a/libs/components/src/form-field/multi-select.stories.ts b/libs/components/src/form-field/multi-select.stories.ts index a68064e07d..123f6602ae 100644 --- a/libs/components/src/form-field/multi-select.stories.ts +++ b/libs/components/src/form-field/multi-select.stories.ts @@ -7,7 +7,7 @@ import { } from "@angular/forms"; import { NgSelectModule } from "@ng-select/ng-select"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -75,209 +75,228 @@ function submit(formObj: FormGroup) { formObj.markAllAsTouched(); } -const MultiSelectTemplate: Story = (args: MultiSelectComponent) => ({ - props: { - formObj: formObjFactory(), - submit: submit, - ...args, - onItemsConfirmed: actionsData.onItemsConfirmed, +type Story = StoryObj; + +export const Loading: Story = { + render: (args) => ({ + props: { + formObj: formObjFactory(), + submit: submit, + ...args, + onItemsConfirmed: actionsData.onItemsConfirmed, + }, + template: ` +
+ + {{ name }} + + + {{ hint }} + + +
+ `, + }), + args: { + baseItems: [] as any, + name: "Loading", + hint: "This is what a loading multi-select looks like", + loading: true, }, - template: ` -
- - {{ name }} - - - {{ hint }} - - -
- `, -}); - -export const Loading = MultiSelectTemplate.bind({}); -Loading.args = { - baseItems: [], - name: "Loading", - hint: "This is what a loading multi-select looks like", - loading: "true", }; -export const Disabled = MultiSelectTemplate.bind({}); -Disabled.args = { - name: "Disabled", - disabled: "true", - hint: "This is what a disabled multi-select looks like", -}; - -export const Groups = MultiSelectTemplate.bind({}); -Groups.args = { - name: "Select groups", - hint: "Groups will be assigned to the associated member", - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, - { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, - ], -}; - -export const Members = MultiSelectTemplate.bind({}); -Members.args = { - name: "Select members", - hint: "Members will be assigned to the associated group/collection", - baseItems: [ - { id: "1", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, - { - id: "2", - listName: "Tania Stone (tstone@mail.me)", - labelName: "Tania Stone", - icon: "bwi-user", - }, - { - id: "3", - listName: "Matt Matters (mmatters@mail.me)", - labelName: "Matt Matters", - icon: "bwi-user", - }, - { - id: "4", - listName: "Bob Robertson (brobertson@mail.me)", - labelName: "Bob Robertson", - icon: "bwi-user", - }, - { - id: "5", - listName: "Ashley Fletcher (aflectcher@mail.me)", - labelName: "Ashley Fletcher", - icon: "bwi-user", - }, - { id: "6", listName: "Rita Olson (rolson@mail.me)", labelName: "Rita Olson", icon: "bwi-user" }, - { - id: "7", - listName: "Final listName (fname@mail.me)", - labelName: "(fname@mail.me)", - icon: "bwi-user", - }, - ], -}; - -export const Collections = MultiSelectTemplate.bind({}); -Collections.args = { - name: "Select collections", - hint: "Collections will be assigned to the associated member", - baseItems: [ - { id: "1", listName: "Collection 1", labelName: "Collection 1", icon: "bwi-collection" }, - { id: "2", listName: "Collection 2", labelName: "Collection 2", icon: "bwi-collection" }, - { id: "3", listName: "Collection 3", labelName: "Collection 3", icon: "bwi-collection" }, - { - id: "3.5", - listName: "Child Collection 1 for Parent 1", - labelName: "Child Collection 1 for Parent 1", - icon: "bwi-collection", - parentGrouping: "Parent 1", - }, - { - id: "3.55", - listName: "Child Collection 2 for Parent 1", - labelName: "Child Collection 2 for Parent 1", - icon: "bwi-collection", - parentGrouping: "Parent 1", - }, - { - id: "3.59", - listName: "Child Collection 3 for Parent 1", - labelName: "Child Collection 3 for Parent 1", - icon: "bwi-collection", - parentGrouping: "Parent 1", - }, - { - id: "3.75", - listName: "Child Collection 1 for Parent 2", - labelName: "Child Collection 1 for Parent 2", - icon: "bwi-collection", - parentGrouping: "Parent 2", - }, - { id: "4", listName: "Collection 4", labelName: "Collection 4", icon: "bwi-collection" }, - { id: "5", listName: "Collection 5", labelName: "Collection 5", icon: "bwi-collection" }, - { id: "6", listName: "Collection 6", labelName: "Collection 6", icon: "bwi-collection" }, - { id: "7", listName: "Collection 7", labelName: "Collection 7", icon: "bwi-collection" }, - ], -}; - -export const MembersAndGroups = MultiSelectTemplate.bind({}); -MembersAndGroups.args = { - name: "Select groups and members", - hint: "Members/Groups will be assigned to the associated collection", - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, - { - id: "7", - listName: "Tania Stone (tstone@mail.me)", - labelName: "(tstone@mail.me)", - icon: "bwi-user", - }, - ], -}; - -export const RemoveSelected = MultiSelectTemplate.bind({}); -RemoveSelected.args = { - name: "Select groups", - hint: "Groups will be removed from the list once the dropdown is closed", - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, - { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, - ], - removeSelectedItems: "true", -}; - -const StandaloneTemplate: Story = (args: MultiSelectComponent) => ({ - props: { - ...args, - onItemsConfirmed: actionsData.onItemsConfirmed, +export const Disabled: Story = { + ...Loading, + args: { + name: "Disabled", + disabled: true, + hint: "This is what a disabled multi-select looks like", + }, +}; + +export const Groups: Story = { + ...Loading, + args: { + name: "Select groups", + hint: "Groups will be assigned to the associated member", + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, + { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, + ], + }, +}; + +export const Members: Story = { + ...Loading, + args: { + name: "Select members", + hint: "Members will be assigned to the associated group/collection", + baseItems: [ + { id: "1", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, + { + id: "2", + listName: "Tania Stone (tstone@mail.me)", + labelName: "Tania Stone", + icon: "bwi-user", + }, + { + id: "3", + listName: "Matt Matters (mmatters@mail.me)", + labelName: "Matt Matters", + icon: "bwi-user", + }, + { + id: "4", + listName: "Bob Robertson (brobertson@mail.me)", + labelName: "Bob Robertson", + icon: "bwi-user", + }, + { + id: "5", + listName: "Ashley Fletcher (aflectcher@mail.me)", + labelName: "Ashley Fletcher", + icon: "bwi-user", + }, + { + id: "6", + listName: "Rita Olson (rolson@mail.me)", + labelName: "Rita Olson", + icon: "bwi-user", + }, + { + id: "7", + listName: "Final listName (fname@mail.me)", + labelName: "(fname@mail.me)", + icon: "bwi-user", + }, + ], + }, +}; + +export const Collections: Story = { + ...Loading, + args: { + name: "Select collections", + hint: "Collections will be assigned to the associated member", + baseItems: [ + { id: "1", listName: "Collection 1", labelName: "Collection 1", icon: "bwi-collection" }, + { id: "2", listName: "Collection 2", labelName: "Collection 2", icon: "bwi-collection" }, + { id: "3", listName: "Collection 3", labelName: "Collection 3", icon: "bwi-collection" }, + { + id: "3.5", + listName: "Child Collection 1 for Parent 1", + labelName: "Child Collection 1 for Parent 1", + icon: "bwi-collection", + parentGrouping: "Parent 1", + }, + { + id: "3.55", + listName: "Child Collection 2 for Parent 1", + labelName: "Child Collection 2 for Parent 1", + icon: "bwi-collection", + parentGrouping: "Parent 1", + }, + { + id: "3.59", + listName: "Child Collection 3 for Parent 1", + labelName: "Child Collection 3 for Parent 1", + icon: "bwi-collection", + parentGrouping: "Parent 1", + }, + { + id: "3.75", + listName: "Child Collection 1 for Parent 2", + labelName: "Child Collection 1 for Parent 2", + icon: "bwi-collection", + parentGrouping: "Parent 2", + }, + { id: "4", listName: "Collection 4", labelName: "Collection 4", icon: "bwi-collection" }, + { id: "5", listName: "Collection 5", labelName: "Collection 5", icon: "bwi-collection" }, + { id: "6", listName: "Collection 6", labelName: "Collection 6", icon: "bwi-collection" }, + { id: "7", listName: "Collection 7", labelName: "Collection 7", icon: "bwi-collection" }, + ], + }, +}; + +export const MembersAndGroups: Story = { + ...Loading, + args: { + name: "Select groups and members", + hint: "Members/Groups will be assigned to the associated collection", + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, + { + id: "7", + listName: "Tania Stone (tstone@mail.me)", + labelName: "(tstone@mail.me)", + icon: "bwi-user", + }, + ], + }, +}; + +export const RemoveSelected: Story = { + ...Loading, + args: { + name: "Select groups", + hint: "Groups will be removed from the list once the dropdown is closed", + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, + { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, + ], + removeSelectedItems: true, + }, +}; + +export const Standalone: Story = { + render: (args) => ({ + props: { + ...args, + onItemsConfirmed: actionsData.onItemsConfirmed, + }, + template: ` + + + `, + }), + args: { + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, + { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, + ], + removeSelectedItems: true, }, - template: ` - - - `, -}); - -export const Standalone = StandaloneTemplate.bind({}); -Standalone.args = { - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, - { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, - ], - removeSelectedItems: "true", }; diff --git a/libs/components/src/form-field/password-input-toggle.stories.ts b/libs/components/src/form-field/password-input-toggle.stories.ts index f39974615b..a1e916b5e1 100644 --- a/libs/components/src/form-field/password-input-toggle.stories.ts +++ b/libs/components/src/form-field/password-input-toggle.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -38,49 +38,42 @@ export default { }, } as Meta; -const Template: Story = ( - args: BitPasswordInputToggleDirective -) => ({ - props: { - ...args, - }, - template: ` -
- - Password - - - -
- `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.props = {}; - -const TemplateBinding: Story = ( - args: BitPasswordInputToggleDirective -) => ({ - props: { - ...args, - }, - template: ` -
- - Password - - - - - -
- `, -}); - -export const Binding = TemplateBinding.bind({}); -Binding.props = { - toggled: false, +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` +
+ + Password + + + +
+ `, + }), +}; + +export const Binding: Story = { + render: (args) => ({ + props: args, + template: ` +
+ + Password + + + + + +
+ `, + }), + args: { + toggled: false, + }, }; diff --git a/libs/components/src/form/form.stories.ts b/libs/components/src/form/form.stories.ts index 45409850b3..4c0b05a083 100644 --- a/libs/components/src/form/form.stories.ts +++ b/libs/components/src/form/form.stories.ts @@ -7,7 +7,7 @@ import { ValidatorFn, Validators, } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -81,67 +81,70 @@ function forbiddenNameValidator(nameRe: RegExp): ValidatorFn { }; } -const FullExampleTemplate: Story = (args) => ({ - props: { - formObj: exampleFormObj, - submit: () => exampleFormObj.markAllAsTouched(), - ...args, +type Story = StoryObj; + +export const FullExample: Story = { + render: (args) => ({ + props: { + formObj: exampleFormObj, + submit: () => exampleFormObj.markAllAsTouched(), + ...args, + }, + template: ` +
+ + Name + + + + + Email + + + + + Country + + + + + + + Age + + + + + Agree to terms + + Required for the service to work properly + + + + Subscribe to updates? + + Yes + + + No + + + Decide later + + + + +
+ `, + }), + + args: { + countries, }, - template: ` -
- - Name - - - - - Email - - - - - Country - - - - - - - Age - - - - - Agree to terms - - Required for the service to work properly - - - - Subscribe to updates? - - Yes - - - No - - - Decide later - - - - -
- `, -}); - -export const FullExample = FullExampleTemplate.bind({}); -FullExample.args = { - countries, }; diff --git a/libs/components/src/icon-button/icon-button.stories.ts b/libs/components/src/icon-button/icon-button.stories.ts index 944b50da72..4a0c56fbde 100644 --- a/libs/components/src/icon-button/icon-button.stories.ts +++ b/libs/components/src/icon-button/icon-button.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { BitIconButtonComponent, IconButtonType } from "./icon-button.component"; @@ -31,68 +31,72 @@ export default { }, } as Meta; -const Template: Story = (args: BitIconButtonComponent) => ({ - props: { ...args, buttonTypes }, - template: ` - - - - - - - +type Story = StoryObj; - - - - - - - - - - - - - - - - -
{{buttonType}}
Default - -
Disabled - -
Loading - -
- `, -}); - -export const Default = Template.bind({}); -Default.args = { - size: "default", +export const Default: Story = { + render: (args: BitIconButtonComponent) => ({ + props: { ...args, buttonTypes }, + template: ` + + + + + + + + + + + + + + + + + + + + + + + + +
{{buttonType}}
Default + +
Disabled + +
Loading + +
+ `, + }), + args: { + size: "default", + }, }; -export const Small = Template.bind({}); -Small.args = { - size: "small", +export const Small: Story = { + ...Default, + args: { + size: "small", + }, }; diff --git a/libs/components/src/icon/icon.stories.ts b/libs/components/src/icon/icon.stories.ts index a67516f2e8..95bf457517 100644 --- a/libs/components/src/icon/icon.stories.ts +++ b/libs/components/src/icon/icon.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { BitIconComponent } from "./icon.component"; @@ -10,18 +10,22 @@ export default { }, } as Meta; -const Template: Story = (args: BitIconComponent) => ({ - props: args, - template: ` -
- -
- `, -}); +type Story = StoryObj; -export const ReportExposedPasswords = Template.bind({}); - -export const UnknownIcon = Template.bind({}); -UnknownIcon.args = { - icon: "unknown", +export const ReportExposedPasswords: Story = { + render: (args) => ({ + props: args, + template: ` +
+ +
+ `, + }), +}; + +export const UnknownIcon: Story = { + ...ReportExposedPasswords, + args: { + icon: "unknown" as any, + }, }; diff --git a/libs/components/src/index.ts b/libs/components/src/index.ts index 7abe0864aa..dbc4f0b494 100644 --- a/libs/components/src/index.ts +++ b/libs/components/src/index.ts @@ -12,6 +12,7 @@ export * from "./dialog"; export * from "./form-field"; export * from "./icon-button"; export * from "./icon"; +export * from "./input"; export * from "./link"; export * from "./menu"; export * from "./multi-select"; diff --git a/libs/components/src/input/index.ts b/libs/components/src/input/index.ts new file mode 100644 index 0000000000..4036b8ab94 --- /dev/null +++ b/libs/components/src/input/index.ts @@ -0,0 +1 @@ +export * from "./input.module"; diff --git a/libs/components/src/link/link.stories.ts b/libs/components/src/link/link.stories.ts index 7ffc6fd2e2..76bb4d4752 100644 --- a/libs/components/src/link/link.stories.ts +++ b/libs/components/src/link/link.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { AnchorLinkDirective, ButtonLinkDirective } from "./link.directive"; import { LinkModule } from "./link.module"; @@ -24,97 +24,99 @@ export default { }, } as Meta; -const ButtonTemplate: Story = (args: ButtonLinkDirective) => ({ - props: args, - template: ` -
-
- -
-
- -
-
- -
-
- -
-
- `, -}); +type Story = StoryObj; -const AnchorTemplate: Story = (args: AnchorLinkDirective) => ({ - props: args, - template: ` -
-
- Anchor +export const Buttons: Story = { + render: (args) => ({ + props: args, + template: ` +
+
+ +
+
+ +
+
+ +
+
+ +
- - - -
- `, -}); - -export const Buttons = ButtonTemplate.bind({}); -Buttons.args = { - linkType: "primary", -}; - -export const Anchors = AnchorTemplate.bind({}); -Anchors.args = { - linkType: "primary", -}; - -const InlineTemplate: Story = (args) => ({ - props: args, - template: ` - - On the internet paragraphs often contain inline links, but few know that can be used for similar purposes. - - `, -}); - -export const Inline = InlineTemplate.bind({}); -Inline.args = { - linkType: "primary", -}; - -const DisabledTemplate: Story = (args) => ({ - props: args, - template: ` - - -
- -
- `, -}); - -export const Disabled = DisabledTemplate.bind({}); -Disabled.parameters = { - controls: { - exclude: ["linkType"], - hideNoControlsWarning: true, + `, + }), + args: { + linkType: "primary", + }, +}; + +export const Anchors: StoryObj = { + render: (args) => ({ + props: args, + template: ` + + `, + }), + args: { + linkType: "primary", + }, +}; + +export const Inline: Story = { + render: (args) => ({ + props: args, + template: ` + + On the internet paragraphs often contain inline links, but few know that can be used for similar purposes. + + `, + }), + args: { + linkType: "primary", + }, +}; + +export const Disabled: Story = { + render: (args) => ({ + props: args, + template: ` + + +
+ +
+ `, + }), + parameters: { + controls: { + exclude: ["linkType"], + hideNoControlsWarning: true, + }, }, }; diff --git a/libs/components/src/menu/menu.stories.ts b/libs/components/src/menu/menu.stories.ts index 786e7ca688..d0f78ed66d 100644 --- a/libs/components/src/menu/menu.stories.ts +++ b/libs/components/src/menu/menu.stories.ts @@ -1,5 +1,5 @@ import { OverlayModule } from "@angular/cdk/overlay"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { ButtonModule } from "../button/button.module"; @@ -30,40 +30,42 @@ export default { }, } as Meta; -const Template: Story = (args: MenuTriggerForDirective) => ({ - props: args, - template: ` - - Anchor link - Another link - - - - +type Story = StoryObj; -
-
- +export const OpenMenu: Story = { + render: (args) => ({ + props: args, + template: ` + + Anchor link + Another link + + + + + +
+
+ +
-
- `, -}); - -const TemplateWithButton: Story = (args: MenuTriggerForDirective) => ({ - props: args, - template: ` -
- -
- - - Anchor link - Another link - - - - `, -}); - -export const OpenMenu = Template.bind({}); -export const ClosedMenu = TemplateWithButton.bind({}); + `, + }), +}; +export const ClosedMenu: Story = { + render: (args) => ({ + props: args, + template: ` +
+ +
+ + + Anchor link + Another link + + + + `, + }), +}; diff --git a/libs/components/src/navigation/nav-group.stories.ts b/libs/components/src/navigation/nav-group.stories.ts index 1c22e2bfc7..5b6e5b807c 100644 --- a/libs/components/src/navigation/nav-group.stories.ts +++ b/libs/components/src/navigation/nav-group.stories.ts @@ -1,5 +1,5 @@ import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { StoryObj, Meta, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -36,9 +36,10 @@ export default { }, } as Meta; -export const Default: Story = (args) => ({ - props: args, - template: ` +export const Default: StoryObj = { + render: (args) => ({ + props: args, + template: ` @@ -50,25 +51,28 @@ export const Default: Story = (args) => ({ `, -}); + }), +}; -export const Tree: Story = (args) => ({ - props: args, - template: ` - - - - - - - - +export const Tree: StoryObj = { + render: (args) => ({ + props: args, + template: ` + + + + + + + + + + + - - + - - - `, -}); + `, + }), +}; diff --git a/libs/components/src/navigation/nav-item.stories.ts b/libs/components/src/navigation/nav-item.stories.ts index e1a7128922..47960f874f 100644 --- a/libs/components/src/navigation/nav-item.stories.ts +++ b/libs/components/src/navigation/nav-item.stories.ts @@ -1,5 +1,5 @@ import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { StoryObj, Meta, moduleMetadata } from "@storybook/angular"; import { IconButtonModule } from "../icon-button"; @@ -23,35 +23,42 @@ export default { }, } as Meta; -const Template: Story = (args: NavItemComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = { - text: "Hello World", - icon: "bwi-filter", +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), + args: { + text: "Hello World", + icon: "bwi-filter", + }, }; -export const WithoutIcon = Template.bind({}); -WithoutIcon.args = { - text: "Hello World", - icon: "", +export const WithoutIcon: Story = { + ...Default, + args: { + text: "Hello World", + icon: "", + }, }; -export const WithoutRoute: Story = (args: NavItemComponent) => ({ - props: args, - template: ` - - `, -}); +export const WithoutRoute: Story = { + render: (args: NavItemComponent) => ({ + props: args, + template: ` + + `, + }), +}; -export const WithChildButtons: Story = (args: NavItemComponent) => ({ - props: args, - template: ` +export const WithChildButtons: Story = { + render: (args: NavItemComponent) => ({ + props: args, + template: ` `, -}); + }), +}; -export const MultipleItemsWithDivider: Story = (args: NavItemComponent) => ({ - props: args, - template: ` - - - - - - `, -}); +export const MultipleItemsWithDivider: Story = { + render: (args: NavItemComponent) => ({ + props: args, + template: ` + + + + + + `, + }), +}; diff --git a/libs/components/src/no-items/no-items.stories.ts b/libs/components/src/no-items/no-items.stories.ts index 0b08aafbc1..d8e5b59bdb 100644 --- a/libs/components/src/no-items/no-items.stories.ts +++ b/libs/components/src/no-items/no-items.stories.ts @@ -1,11 +1,13 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { ButtonModule } from "../button"; +import { NoItemsComponent } from "./no-items.component"; import { NoItemsModule } from "./no-items.module"; export default { title: "Component Library/No Items", + component: NoItemsComponent, decorators: [ moduleMetadata({ imports: [ButtonModule, NoItemsModule], @@ -13,23 +15,25 @@ export default { ], } as Meta; -const Template: Story = (args) => ({ - props: args, - template: ` - - No items found - Your description here. - - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + No items found + Your description here. + + + `, + }), +}; diff --git a/libs/components/src/progress/progress.stories.ts b/libs/components/src/progress/progress.stories.ts index 079f936e3a..49a5398d2d 100644 --- a/libs/components/src/progress/progress.stories.ts +++ b/libs/components/src/progress/progress.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { ProgressComponent } from "./progress.component"; @@ -18,22 +18,23 @@ export default { }, } as Meta; -const Template: Story = (args: ProgressComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Empty = Template.bind({}); -Empty.args = { - barWidth: 0, +export const Empty: Story = { + args: { + barWidth: 0, + }, }; -export const Full = Template.bind({}); -Full.args = { - barWidth: 100, +export const Full: Story = { + args: { + barWidth: 100, + }, }; -export const CustomText = Template.bind({}); -CustomText.args = { - barWidth: 25, - text: "Loading...", +export const CustomText: Story = { + args: { + barWidth: 25, + text: "Loading...", + }, }; diff --git a/libs/components/src/radio-button/radio-button.stories.ts b/libs/components/src/radio-button/radio-button.stories.ts index 340e76c421..d3c5716698 100644 --- a/libs/components/src/radio-button/radio-button.stories.ts +++ b/libs/components/src/radio-button/radio-button.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule, FormControl, FormGroup } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -34,65 +34,67 @@ export default { url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=3930%3A16850&t=xXPx6GJYsJfuMQPE-4", }, }, -} as Meta; +} as Meta; -const InlineTemplate: Story = (args: RadioGroupComponent) => ({ - props: { - formObj: new FormGroup({ - radio: new FormControl(0), - }), - }, - template: ` -
- - Group of radio buttons +type Story = StoryObj; - - First - +export const Inline: Story = { + render: () => ({ + props: { + formObj: new FormGroup({ + radio: new FormControl(0), + }), + }, + template: ` + + + Group of radio buttons + + + First + + + + Second + + + + Third + + + + `, + }), +}; - - Second - - - - Third - -
- - `, -}); - -export const Inline = InlineTemplate.bind({}); - -const BlockTemplate: Story = (args: RadioGroupComponent) => ({ - props: { - formObj: new FormGroup({ - radio: new FormControl(0), - }), - }, - template: ` -
- - Group of radio buttons - - - First - This is a hint for the first option - - - - Second - This is a hint for the second option - - - - Third - This is a hint for the third option - - -
- `, -}); - -export const Block = BlockTemplate.bind({}); +export const Block: Story = { + render: () => ({ + props: { + formObj: new FormGroup({ + radio: new FormControl(0), + }), + }, + template: ` +
+ + Group of radio buttons + + + First + This is a hint for the first option + + + + Second + This is a hint for the second option + + + + Third + This is a hint for the third option + + +
+ `, + }), +}; diff --git a/libs/components/src/search/search.stories.ts b/libs/components/src/search/search.stories.ts index 0968e9b6ed..3167c5c7d4 100644 --- a/libs/components/src/search/search.stories.ts +++ b/libs/components/src/search/search.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -29,12 +29,14 @@ export default { ], } as Meta; -const Template: Story = (args: SearchComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = {}; +export const Default: Story = { + render: (args: SearchComponent) => ({ + props: args, + template: ` + + `, + }), + args: {}, +}; diff --git a/libs/components/src/select/select.stories.ts b/libs/components/src/select/select.stories.ts index 9b38b05d6c..540279dab0 100644 --- a/libs/components/src/select/select.stories.ts +++ b/libs/components/src/select/select.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -37,22 +37,26 @@ export default { }, } as Meta; -const DefaultTemplate: Story = (args: MultiSelectComponent) => ({ - props: { - ...args, - }, - template: ` - - - - - `, -}); +type Story = StoryObj; -export const Default = DefaultTemplate.bind({}); -Default.args = {}; - -export const Disabled = DefaultTemplate.bind({}); -Disabled.args = { - disabled: true, +export const Default: Story = { + render: (args) => ({ + props: { + ...args, + }, + template: ` + + + + + `, + }), + args: {}, +}; + +export const Disabled: Story = { + ...Default, + args: { + disabled: true, + }, }; diff --git a/libs/components/src/stories/colors.stories.mdx b/libs/components/src/stories/colors.mdx similarity index 98% rename from libs/components/src/stories/colors.stories.mdx rename to libs/components/src/stories/colors.mdx index 57a15314e0..d77c726b26 100644 --- a/libs/components/src/stories/colors.stories.mdx +++ b/libs/components/src/stories/colors.mdx @@ -67,7 +67,8 @@ export const Table = (args) => ( ); - + `} + # Colors diff --git a/libs/components/src/stories/forms-docs.stories.mdx b/libs/components/src/stories/forms.mdx similarity index 97% rename from libs/components/src/stories/forms-docs.stories.mdx rename to libs/components/src/stories/forms.mdx index 0d8c94857c..f677684a9d 100644 --- a/libs/components/src/stories/forms-docs.stories.mdx +++ b/libs/components/src/stories/forms.mdx @@ -1,6 +1,6 @@ import { Meta, Story, Source } from "@storybook/addon-docs"; - + # Forms diff --git a/libs/components/src/stories/icons.stories.mdx b/libs/components/src/stories/icons.mdx similarity index 99% rename from libs/components/src/stories/icons.stories.mdx rename to libs/components/src/stories/icons.mdx index 1a74a8f4ec..b3a4cbbf99 100644 --- a/libs/components/src/stories/icons.stories.mdx +++ b/libs/components/src/stories/icons.mdx @@ -1,6 +1,6 @@ - +{/* Iconography.stories.mdx */} -import { Meta } from "@storybook/addon-docs/"; +import { Meta } from "@storybook/addon-docs"; diff --git a/libs/components/src/stories/input-docs.stories.mdx b/libs/components/src/stories/input.mdx similarity index 95% rename from libs/components/src/stories/input-docs.stories.mdx rename to libs/components/src/stories/input.mdx index 7f9b824354..0fd1a4890b 100644 --- a/libs/components/src/stories/input-docs.stories.mdx +++ b/libs/components/src/stories/input.mdx @@ -1,8 +1,8 @@ import { Meta } from "@storybook/addon-docs"; - + -# `bitInput` +# Input `bitInput` is an Angular directive to be used on ``, `