From 3932f3496588c41ca1d079252fe0431218426129 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 12:56:36 +0100 Subject: [PATCH 001/124] [deps] Platform (CL): Update storybook monorepo to v7.6.17 (#7814) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 2087 +++++++++++++-------------------------------- package.json | 14 +- 2 files changed, 595 insertions(+), 1506 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d90ef10b14..30a5d44715d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,13 +84,13 @@ "@electron/notarize": "2.3.0", "@electron/rebuild": "3.6.0", "@ngtools/webpack": "16.2.11", - "@storybook/addon-a11y": "7.6.4", - "@storybook/addon-actions": "7.6.4", + "@storybook/addon-a11y": "7.6.17", + "@storybook/addon-actions": "7.6.17", "@storybook/addon-designs": "7.0.7", - "@storybook/addon-essentials": "7.6.4", - "@storybook/addon-interactions": "7.6.4", - "@storybook/addon-links": "7.6.4", - "@storybook/angular": "7.6.4", + "@storybook/addon-essentials": "7.6.17", + "@storybook/addon-interactions": "7.6.17", + "@storybook/addon-links": "7.6.17", + "@storybook/angular": "7.6.17", "@storybook/jest": "0.2.3", "@storybook/testing-library": "0.2.2", "@types/argon2-browser": "1.18.1", @@ -171,7 +171,7 @@ "rimraf": "5.0.5", "sass": "1.69.5", "sass-loader": "13.3.2", - "storybook": "7.6.4", + "storybook": "7.6.17", "style-loader": "3.3.3", "tailwindcss": "3.3.5", "ts-jest": "29.1.2", @@ -2007,9 +2007,9 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", - "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -2407,9 +2407,9 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", - "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -2505,16 +2505,15 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz", - "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==", + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-split-export-declaration": "^7.22.6", @@ -2795,9 +2794,9 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", - "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", @@ -7089,12 +7088,12 @@ } }, "node_modules/@storybook/addon-a11y": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-7.6.4.tgz", - "integrity": "sha512-NwROJMes3D1WVPSmASVnHtDCIFQCF3DoPJEpzpnUYFxCR2IQzqPSlf9jptRkot6XjL5XwVX5mV2KxC2lKA1cfg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-7.6.17.tgz", + "integrity": "sha512-UYHJAKQpJMCu4X4O/325UqozYrkhPn2VyQdwPgC+uiOKZvrtni4uRbpOspeyjC0wXH1tDbY8WZvxwvwQryYkpA==", "dev": true, "dependencies": { - "@storybook/addon-highlight": "7.6.4", + "@storybook/addon-highlight": "7.6.17", "axe-core": "^4.2.0" }, "funding": { @@ -7103,12 +7102,12 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.6.4.tgz", - "integrity": "sha512-91UD5KPDik74VKVioPMcbwwvDXN/non8p1wArYAHCHCmd/Pts5MJRiFueSdfomSpNjUtjtn6eSXtwpIL3XVOfQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.6.17.tgz", + "integrity": "sha512-TBphs4v6LRfyTpFo/WINF0TkMaE3rrNog7wW5mbz6n0j8o53kDN4o9ZEcygSL5zQX43CAaghQTeDCss7ueG7ZQ==", "dev": true, "dependencies": { - "@storybook/core-events": "7.6.4", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "@types/uuid": "^9.0.1", "dequal": "^2.0.2", @@ -7121,9 +7120,9 @@ } }, "node_modules/@storybook/addon-actions/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -7147,9 +7146,9 @@ } }, "node_modules/@storybook/addon-backgrounds": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.6.4.tgz", - "integrity": "sha512-gNy3kIkHSr+Lg/jVDHwbZjIe1po5SDGZNVe39vrJwnqGz8T1clWes9WHCL6zk/uaCDA3yUna2Nt/KlOFAWDSoQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.6.17.tgz", + "integrity": "sha512-7dize7x8+37PH77kmt69b0xSaeDqOcZ4fpzW6+hk53hIaCVU26eGs4+j+743Xva31eOgZWNLupUhOpUDc6SqZw==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -7162,12 +7161,12 @@ } }, "node_modules/@storybook/addon-controls": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.6.4.tgz", - "integrity": "sha512-k4AtZfazmD/nL3JAtLGAB7raPhkhUo0jWnaZWrahd9h1Fm13mBU/RW+JzTRhCw3Mp2HPERD7NI5Qcd2fUP6WDA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.6.17.tgz", + "integrity": "sha512-zR0aLaUF7FtV/nMRyfniFbCls/e0DAAoXACuOAUAwNAv0lbIS8AyZZiHSmKucCvziUQ6WceeCC7+du3C+9y0rQ==", "dev": true, "dependencies": { - "@storybook/blocks": "7.6.4", + "@storybook/blocks": "7.6.17", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" }, @@ -7204,26 +7203,26 @@ } }, "node_modules/@storybook/addon-docs": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.6.4.tgz", - "integrity": "sha512-PbFMbvC9sK3sGdMhwmagXs9TqopTp9FySji+L8O7W9SHRC6wSmdwoWWPWybkOYxr/z/wXi7EM0azSAX7yQxLbw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.6.17.tgz", + "integrity": "sha512-FKa4Mdy7nhgvEVZJHpMkHriDzpVHbohn87zv9NCL+Ctjs1iAmzGwxEm0culszyDS1HN2ToVoY0h8CSi2RSSZqA==", "dev": true, "dependencies": { "@jest/transform": "^29.3.1", "@mdx-js/react": "^2.1.5", - "@storybook/blocks": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/components": "7.6.4", - "@storybook/csf-plugin": "7.6.4", - "@storybook/csf-tools": "7.6.4", + "@storybook/blocks": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/components": "7.6.17", + "@storybook/csf-plugin": "7.6.17", + "@storybook/csf-tools": "7.6.17", "@storybook/global": "^5.0.0", "@storybook/mdx2-csf": "^1.0.0", - "@storybook/node-logger": "7.6.4", - "@storybook/postinstall": "7.6.4", - "@storybook/preview-api": "7.6.4", - "@storybook/react-dom-shim": "7.6.4", - "@storybook/theming": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/node-logger": "7.6.17", + "@storybook/postinstall": "7.6.17", + "@storybook/preview-api": "7.6.17", + "@storybook/react-dom-shim": "7.6.17", + "@storybook/theming": "7.6.17", + "@storybook/types": "7.6.17", "fs-extra": "^11.1.0", "remark-external-links": "^8.0.0", "remark-slug": "^6.0.0", @@ -7239,13 +7238,13 @@ } }, "node_modules/@storybook/addon-docs/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -7257,9 +7256,9 @@ } }, "node_modules/@storybook/addon-docs/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -7270,9 +7269,9 @@ } }, "node_modules/@storybook/addon-docs/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -7283,17 +7282,17 @@ } }, "node_modules/@storybook/addon-docs/node_modules/@storybook/preview-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.4.tgz", - "integrity": "sha512-KhisNdQX5NdfAln+spLU4B82d804GJQp/CnI5M1mm/taTnjvMgs/wTH9AmR89OPoq+tFZVW0vhy2zgPS3ar71A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", + "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -7309,13 +7308,13 @@ } }, "node_modules/@storybook/addon-docs/node_modules/@storybook/theming": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.4.tgz", - "integrity": "sha512-Z/dcC5EpkIXelYCkt9ojnX6D7qGOng8YHxV/OWlVE9TrEGYVGPOEfwQryR0RhmGpDha1TYESLYrsDb4A8nJ1EA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.17.tgz", + "integrity": "sha512-ZbaBt3KAbmBtfjNqgMY7wPMBshhSJlhodyMNQypv+95xLD/R+Az6aBYbpVAOygLaUQaQk4ar7H/Ww6lFIoiFbA==", "dev": true, "dependencies": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.6.4", + "@storybook/client-logger": "7.6.17", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" }, @@ -7329,12 +7328,12 @@ } }, "node_modules/@storybook/addon-docs/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -7359,24 +7358,24 @@ } }, "node_modules/@storybook/addon-essentials": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.6.4.tgz", - "integrity": "sha512-J+zPmP4pbuuFxQ3pjLRYQRnxEtp7jF3xRXGFO8brVnEqtqoxwJ6j3euUrRLe0rpGAU3AD7dYfaaFjd3xkENgTw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.6.17.tgz", + "integrity": "sha512-qlSpamxuYfT2taF953nC9QijGF2pSbg1ewMNpdwLTj16PTZvR/d8NCDMTJujI1bDwM2m18u8Yc43ibh5LEmxCw==", "dev": true, "dependencies": { - "@storybook/addon-actions": "7.6.4", - "@storybook/addon-backgrounds": "7.6.4", - "@storybook/addon-controls": "7.6.4", - "@storybook/addon-docs": "7.6.4", - "@storybook/addon-highlight": "7.6.4", - "@storybook/addon-measure": "7.6.4", - "@storybook/addon-outline": "7.6.4", - "@storybook/addon-toolbars": "7.6.4", - "@storybook/addon-viewport": "7.6.4", - "@storybook/core-common": "7.6.4", - "@storybook/manager-api": "7.6.4", - "@storybook/node-logger": "7.6.4", - "@storybook/preview-api": "7.6.4", + "@storybook/addon-actions": "7.6.17", + "@storybook/addon-backgrounds": "7.6.17", + "@storybook/addon-controls": "7.6.17", + "@storybook/addon-docs": "7.6.17", + "@storybook/addon-highlight": "7.6.17", + "@storybook/addon-measure": "7.6.17", + "@storybook/addon-outline": "7.6.17", + "@storybook/addon-toolbars": "7.6.17", + "@storybook/addon-viewport": "7.6.17", + "@storybook/core-common": "7.6.17", + "@storybook/manager-api": "7.6.17", + "@storybook/node-logger": "7.6.17", + "@storybook/preview-api": "7.6.17", "ts-dedent": "^2.0.0" }, "funding": { @@ -7389,13 +7388,13 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -7407,9 +7406,9 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -7420,9 +7419,9 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -7433,23 +7432,22 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/manager-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.6.4.tgz", - "integrity": "sha512-RFb/iaBJfXygSgXkINPRq8dXu7AxBicTGX7MxqKXbz5FU7ANwV7abH6ONBYURkSDOH9//TQhRlVkF5u8zWg3bw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.6.17.tgz", + "integrity": "sha512-IJIV1Yc6yw1dhCY4tReHCfBnUKDqEBnMyHp3mbXpsaHxnxJZrXO45WjRAZIKlQKhl/Ge1CrnznmHRCmYgqmrWg==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/router": "7.6.4", - "@storybook/theming": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/router": "7.6.17", + "@storybook/theming": "7.6.17", + "@storybook/types": "7.6.17", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", - "semver": "^7.3.7", "store2": "^2.14.2", "telejson": "^7.2.0", "ts-dedent": "^2.0.0" @@ -7460,17 +7458,17 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/preview-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.4.tgz", - "integrity": "sha512-KhisNdQX5NdfAln+spLU4B82d804GJQp/CnI5M1mm/taTnjvMgs/wTH9AmR89OPoq+tFZVW0vhy2zgPS3ar71A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", + "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -7486,12 +7484,12 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/router": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.6.4.tgz", - "integrity": "sha512-5MQ7Z4D7XNPN2yhFgjey7hXOYd6s8CggUqeAwhzGTex90SMCkKHSz1hfkcXn1ZqBPaall2b53uK553OvPLp9KQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.6.17.tgz", + "integrity": "sha512-GnyC0j6Wi5hT4qRhSyT8NPtJfGmf82uZw97LQRWeyYu5gWEshUdM7aj40XlNiScd5cZDp0owO1idduVF2k2l2A==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", + "@storybook/client-logger": "7.6.17", "memoizerific": "^1.11.3", "qs": "^6.10.0" }, @@ -7501,13 +7499,13 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/theming": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.4.tgz", - "integrity": "sha512-Z/dcC5EpkIXelYCkt9ojnX6D7qGOng8YHxV/OWlVE9TrEGYVGPOEfwQryR0RhmGpDha1TYESLYrsDb4A8nJ1EA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.17.tgz", + "integrity": "sha512-ZbaBt3KAbmBtfjNqgMY7wPMBshhSJlhodyMNQypv+95xLD/R+Az6aBYbpVAOygLaUQaQk4ar7H/Ww6lFIoiFbA==", "dev": true, "dependencies": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.6.4", + "@storybook/client-logger": "7.6.17", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" }, @@ -7521,12 +7519,12 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -7537,9 +7535,9 @@ } }, "node_modules/@storybook/addon-highlight": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.6.4.tgz", - "integrity": "sha512-0kvjDzquoPwWWU61QYmEtcSGWXufnV7Z/bfBTYh132uxvV/X9YzDFcXXrxGL7sBJkK32gNUUBDuiTOxs5NxyOQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.6.17.tgz", + "integrity": "sha512-R1yBPUUqGn+60aJakn8q+5Zt34E/gU3n3VmgPdryP0LJUdZ5q1/RZShoVDV+yYQ40htMH6oaCv3OyyPzFAGJ6A==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -7550,13 +7548,13 @@ } }, "node_modules/@storybook/addon-interactions": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-7.6.4.tgz", - "integrity": "sha512-LjK9uhkgnbGyDwwa7pQhLptDEHeTIFmy+KurfJs9T08DpvRFfuuzyW4mj/hA63R1W5yjFSAhRiZj26+D7kBIyw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-7.6.17.tgz", + "integrity": "sha512-6zlX+RDQ1PlA6fp7C+hun8t7h2RXfCGs5dGrhEenp2lqnR/rYuUJRC0tmKpkZBb8kZVcbSChzkB/JYkBjBCzpQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "jest-mock": "^27.0.6", "polished": "^4.2.2", "ts-dedent": "^2.2.0" @@ -7583,13 +7581,13 @@ } }, "node_modules/@storybook/addon-interactions/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -7601,9 +7599,9 @@ } }, "node_modules/@storybook/addon-interactions/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -7614,9 +7612,9 @@ } }, "node_modules/@storybook/addon-interactions/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -7627,12 +7625,12 @@ } }, "node_modules/@storybook/addon-interactions/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -7665,9 +7663,9 @@ } }, "node_modules/@storybook/addon-links": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.6.4.tgz", - "integrity": "sha512-TEhxYdMhJO28gD84ej1FCwLv9oLuCPt77bRXip9ndaNPRTdHYdWv6IP94dhbuDi8eHux7Z4A/mllciFuDFrnCw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.6.17.tgz", + "integrity": "sha512-iFUwKObRn0EKI0zMETsil2p9a/81rCuSMEWECsi+khkCAs1FUnD2cT6Ag5ydcNcBXsdtdfDJdtXQrkw+TSoStQ==", "dev": true, "dependencies": { "@storybook/csf": "^0.1.2", @@ -7688,9 +7686,9 @@ } }, "node_modules/@storybook/addon-measure": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.6.4.tgz", - "integrity": "sha512-73wsJ8PALsgWniR3MA/cmxcFuU6cRruWdIyYzOMgM8ife2Jm3xSkV7cTTXAqXt2H9Uuki4PGnuMHWWFLpPeyVA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.6.17.tgz", + "integrity": "sha512-O5vnHZNkduvZ95jf1UssbOl6ivIxzl5tv+4EpScPYId7w700bxWsJH+QX7ip6KlrCf2o3iUhmPe8bm05ghG2KA==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -7702,9 +7700,9 @@ } }, "node_modules/@storybook/addon-outline": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.6.4.tgz", - "integrity": "sha512-CFxGASRse/qeFocetDKFNeWZ3Aa2wapVtRciDNa4Zx7k1wCnTjEsPIm54waOuCaNVcrvO+nJUAZG5WyiorQvcg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.6.17.tgz", + "integrity": "sha512-9o9JXDsYjNaDgz/cY5+jv694+aik/1aiRGGvsCv68e1p/ob0glkGKav4lnJe2VJqD+gCmaARoD8GOJlhoQl8JQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -7716,9 +7714,9 @@ } }, "node_modules/@storybook/addon-toolbars": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.6.4.tgz", - "integrity": "sha512-ENMQJgU4sRCLLDVXYfa+P3cQVV9PC0ZxwVAKeM3NPYPNH/ODoryGNtq+Q68LwHlM4ObCE2oc9MzaQqPxloFcCw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.6.17.tgz", + "integrity": "sha512-UMrchbUHiyWrh6WuGnpy34Jqzkx/63B+MSgb3CW7YsQaXz64kE0Rol0TNSznnB+mYXplcqH+ndI4r4kFsmgwDg==", "dev": true, "funding": { "type": "opencollective", @@ -7726,9 +7724,9 @@ } }, "node_modules/@storybook/addon-viewport": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.6.4.tgz", - "integrity": "sha512-SoTcHIoqybhYD28v7QExF1EZnl7FfxuP74VDhtze5LyMd2CbqmVnUfwewLCz/3IvCNce0GqdNyg1m6QJ7Eq1uw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.6.17.tgz", + "integrity": "sha512-sA0QCcf4QAMixWvn8uvRYPfkKCSl6JajJaAspoPqXSxHEpK7uwOlpg3kqFU5XJJPXD0X957M+ONgNvBzYqSpEw==", "dev": true, "dependencies": { "memoizerific": "^1.11.3" @@ -7759,24 +7757,24 @@ } }, "node_modules/@storybook/angular": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/angular/-/angular-7.6.4.tgz", - "integrity": "sha512-Yj/LXssJ97d8v3mRjxN8Gf7UXz5qp3wKv+P+L81Hh6CwAOGg7W3USkLgsdRFO4HmwviY1ukbTAzdAucTplHhUQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/angular/-/angular-7.6.17.tgz", + "integrity": "sha512-dKhY7YQrJTitdKfusxBqJHMPezq++vTwdWtKmFHveU8ALS9PJbmMUriuoBQRll9VIwS3E3Y5CyLc7524tYT+3A==", "dev": true, "dependencies": { - "@storybook/builder-webpack5": "7.6.4", - "@storybook/cli": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-common": "7.6.4", - "@storybook/core-events": "7.6.4", - "@storybook/core-server": "7.6.4", - "@storybook/core-webpack": "7.6.4", - "@storybook/docs-tools": "7.6.4", + "@storybook/builder-webpack5": "7.6.17", + "@storybook/cli": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-common": "7.6.17", + "@storybook/core-events": "7.6.17", + "@storybook/core-server": "7.6.17", + "@storybook/core-webpack": "7.6.17", + "@storybook/docs-tools": "7.6.17", "@storybook/global": "^5.0.0", - "@storybook/node-logger": "7.6.4", - "@storybook/preview-api": "7.6.4", - "@storybook/telemetry": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/node-logger": "7.6.17", + "@storybook/preview-api": "7.6.17", + "@storybook/telemetry": "7.6.17", + "@storybook/types": "7.6.17", "@types/node": "^18.0.0", "@types/react": "^16.14.34", "@types/react-dom": "^16.9.14", @@ -7822,13 +7820,13 @@ } }, "node_modules/@storybook/angular/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -7840,9 +7838,9 @@ } }, "node_modules/@storybook/angular/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -7853,9 +7851,9 @@ } }, "node_modules/@storybook/angular/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -7866,17 +7864,17 @@ } }, "node_modules/@storybook/angular/node_modules/@storybook/preview-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.4.tgz", - "integrity": "sha512-KhisNdQX5NdfAln+spLU4B82d804GJQp/CnI5M1mm/taTnjvMgs/wTH9AmR89OPoq+tFZVW0vhy2zgPS3ar71A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", + "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -7892,12 +7890,12 @@ } }, "node_modules/@storybook/angular/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -7908,22 +7906,22 @@ } }, "node_modules/@storybook/blocks": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.6.4.tgz", - "integrity": "sha512-iXinXXhTUBtReREP1Jifpu35DnGg7FidehjvCM8sM4E4aymfb8czdg9DdvG46T2UFUPUct36nnjIdMLWOya8Bw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.6.17.tgz", + "integrity": "sha512-PsNVoe0bX1mMn4Kk3nbKZ0ItDZZ0YJnYAFJ6toAbsyBAbgzg1sce88sQinzvbn58/RT9MPKeWMPB45ZS7ggiNg==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/components": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/components": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", - "@storybook/docs-tools": "7.6.4", + "@storybook/docs-tools": "7.6.17", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.6.4", - "@storybook/preview-api": "7.6.4", - "@storybook/theming": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/manager-api": "7.6.17", + "@storybook/preview-api": "7.6.17", + "@storybook/theming": "7.6.17", + "@storybook/types": "7.6.17", "@types/lodash": "^4.14.167", "color-convert": "^2.0.1", "dequal": "^2.0.2", @@ -7947,13 +7945,13 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -7965,9 +7963,9 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -7978,9 +7976,9 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -7991,23 +7989,22 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/manager-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.6.4.tgz", - "integrity": "sha512-RFb/iaBJfXygSgXkINPRq8dXu7AxBicTGX7MxqKXbz5FU7ANwV7abH6ONBYURkSDOH9//TQhRlVkF5u8zWg3bw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.6.17.tgz", + "integrity": "sha512-IJIV1Yc6yw1dhCY4tReHCfBnUKDqEBnMyHp3mbXpsaHxnxJZrXO45WjRAZIKlQKhl/Ge1CrnznmHRCmYgqmrWg==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/router": "7.6.4", - "@storybook/theming": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/router": "7.6.17", + "@storybook/theming": "7.6.17", + "@storybook/types": "7.6.17", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", - "semver": "^7.3.7", "store2": "^2.14.2", "telejson": "^7.2.0", "ts-dedent": "^2.0.0" @@ -8018,17 +8015,17 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/preview-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.4.tgz", - "integrity": "sha512-KhisNdQX5NdfAln+spLU4B82d804GJQp/CnI5M1mm/taTnjvMgs/wTH9AmR89OPoq+tFZVW0vhy2zgPS3ar71A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", + "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -8044,12 +8041,12 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/router": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.6.4.tgz", - "integrity": "sha512-5MQ7Z4D7XNPN2yhFgjey7hXOYd6s8CggUqeAwhzGTex90SMCkKHSz1hfkcXn1ZqBPaall2b53uK553OvPLp9KQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.6.17.tgz", + "integrity": "sha512-GnyC0j6Wi5hT4qRhSyT8NPtJfGmf82uZw97LQRWeyYu5gWEshUdM7aj40XlNiScd5cZDp0owO1idduVF2k2l2A==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", + "@storybook/client-logger": "7.6.17", "memoizerific": "^1.11.3", "qs": "^6.10.0" }, @@ -8059,13 +8056,13 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/theming": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.4.tgz", - "integrity": "sha512-Z/dcC5EpkIXelYCkt9ojnX6D7qGOng8YHxV/OWlVE9TrEGYVGPOEfwQryR0RhmGpDha1TYESLYrsDb4A8nJ1EA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.17.tgz", + "integrity": "sha512-ZbaBt3KAbmBtfjNqgMY7wPMBshhSJlhodyMNQypv+95xLD/R+Az6aBYbpVAOygLaUQaQk4ar7H/Ww6lFIoiFbA==", "dev": true, "dependencies": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.6.4", + "@storybook/client-logger": "7.6.17", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" }, @@ -8079,12 +8076,12 @@ } }, "node_modules/@storybook/blocks/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -8095,15 +8092,15 @@ } }, "node_modules/@storybook/builder-manager": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.6.4.tgz", - "integrity": "sha512-k5+D3fXw7LdMOWd5tF7cIq8L3irrdW6/vmcEHLaJj1EXZ+DvsNCH9xSsLS+6zfrUcxug4oSfRqvF87w6Oz3DtA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.6.17.tgz", + "integrity": "sha512-Sj8hcDYiPCCMfeLzus37czl0zdrAxAz4IyYam2jBjVymrIrcDAFyL1OCZvnq33ft179QYQWhUs9qwzVmlR/ZWg==", "dev": true, "dependencies": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "7.6.4", - "@storybook/manager": "7.6.4", - "@storybook/node-logger": "7.6.4", + "@storybook/core-common": "7.6.17", + "@storybook/manager": "7.6.17", + "@storybook/node-logger": "7.6.17", "@types/ejs": "^3.1.1", "@types/find-cache-dir": "^3.2.1", "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", @@ -8122,395 +8119,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-manager/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, "node_modules/@storybook/builder-manager/node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", @@ -8526,26 +8134,27 @@ } }, "node_modules/@storybook/builder-webpack5": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-7.6.4.tgz", - "integrity": "sha512-J5wzPn/rsowlur5A7W9pAfN3a5fMapOoHaZsDKUklGRud/JUeabAIVdL1P/eX+yE3xaJk9auYivEWbglSx2Kpg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-7.6.17.tgz", + "integrity": "sha512-GMaBd8/RzivuAmWrYSt9Rga3j8WLcu5LCMYiPVs+XKXsKAC8lTkV0WRWh8Nk6wTmfzsRQ2acwFjSG5oE4ClZKA==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-common": "7.6.4", - "@storybook/core-events": "7.6.4", - "@storybook/core-webpack": "7.6.4", - "@storybook/node-logger": "7.6.4", - "@storybook/preview": "7.6.4", - "@storybook/preview-api": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-common": "7.6.17", + "@storybook/core-events": "7.6.17", + "@storybook/core-webpack": "7.6.17", + "@storybook/node-logger": "7.6.17", + "@storybook/preview": "7.6.17", + "@storybook/preview-api": "7.6.17", "@swc/core": "^1.3.82", "@types/node": "^18.0.0", "@types/semver": "^7.3.4", "babel-loader": "^9.0.0", "browser-assert": "^1.2.1", "case-sensitive-paths-webpack-plugin": "^2.4.0", + "cjs-module-lexer": "^1.2.3", "constants-browserify": "^1.0.0", "css-loader": "^6.7.1", "es-module-lexer": "^1.4.1", @@ -8580,13 +8189,13 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -8598,9 +8207,9 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -8611,9 +8220,9 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -8624,17 +8233,17 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@storybook/preview-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.4.tgz", - "integrity": "sha512-KhisNdQX5NdfAln+spLU4B82d804GJQp/CnI5M1mm/taTnjvMgs/wTH9AmR89OPoq+tFZVW0vhy2zgPS3ar71A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", + "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -8650,12 +8259,12 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -8711,23 +8320,23 @@ } }, "node_modules/@storybook/cli": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.6.4.tgz", - "integrity": "sha512-GqvaFdkkBMJOdnrVe82XY0V3b+qFMhRNyVoTv2nqB87iMUXZHqh4Pu4LqwaJBsBpuNregvCvVOPe9LGgoOzy4A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.6.17.tgz", + "integrity": "sha512-1sCo+nCqyR+nKfTcEidVu8XzNoECC7Y1l+uW38/r7s2f/TdDorXaIGAVrpjbSaXSoQpx5DxYJVaKCcQuOgqwcA==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", "@babel/preset-env": "^7.23.2", "@babel/types": "^7.23.0", "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "7.6.4", - "@storybook/core-common": "7.6.4", - "@storybook/core-events": "7.6.4", - "@storybook/core-server": "7.6.4", - "@storybook/csf-tools": "7.6.4", - "@storybook/node-logger": "7.6.4", - "@storybook/telemetry": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/codemod": "7.6.17", + "@storybook/core-common": "7.6.17", + "@storybook/core-events": "7.6.17", + "@storybook/core-server": "7.6.17", + "@storybook/csf-tools": "7.6.17", + "@storybook/node-logger": "7.6.17", + "@storybook/telemetry": "7.6.17", + "@storybook/types": "7.6.17", "@types/semver": "^7.3.4", "@yarnpkg/fslib": "2.10.3", "@yarnpkg/libzip": "2.3.0", @@ -8752,7 +8361,6 @@ "puppeteer-core": "^2.1.1", "read-pkg-up": "^7.0.1", "semver": "^7.3.7", - "simple-update-notifier": "^2.0.0", "strip-json-comments": "^3.0.1", "tempy": "^1.0.1", "ts-dedent": "^2.0.0", @@ -8767,22 +8375,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/cli/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", - "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/@storybook/cli/node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", @@ -8918,13 +8510,13 @@ } }, "node_modules/@storybook/cli/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -8936,9 +8528,9 @@ } }, "node_modules/@storybook/cli/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -8949,9 +8541,9 @@ } }, "node_modules/@storybook/cli/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -8962,12 +8554,12 @@ } }, "node_modules/@storybook/cli/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -8977,41 +8569,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/cli/node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", - "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.4", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@storybook/cli/node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@storybook/cli/node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", - "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.4" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/@storybook/cli/node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", @@ -9050,18 +8607,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/@storybook/cli/node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@storybook/client-logger": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.2.2.tgz", @@ -9077,18 +8622,18 @@ } }, "node_modules/@storybook/codemod": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.6.4.tgz", - "integrity": "sha512-q4rZVOfozxzbDRH/LzuFDoIGBdXs+orAm18fi6iAx8PeMHe8J/MOXKccNV1zdkm/h7mTQowuRo45KwJHw8vX+g==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.6.17.tgz", + "integrity": "sha512-JuTmf2u3C4fCnjO7o3dqRgrq3ozNYfWlrRP8xuIdvT7niMap7a396hJtSKqS10FxCgKFcMAOsRgrCalH1dWxUg==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", "@babel/preset-env": "^7.23.2", "@babel/types": "^7.23.0", "@storybook/csf": "^0.1.2", - "@storybook/csf-tools": "7.6.4", - "@storybook/node-logger": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/csf-tools": "7.6.17", + "@storybook/node-logger": "7.6.17", + "@storybook/types": "7.6.17", "@types/cross-spawn": "^6.0.2", "cross-spawn": "^7.0.3", "globby": "^11.0.2", @@ -9102,22 +8647,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/codemod/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", - "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/@storybook/codemod/node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", @@ -9136,9 +8665,9 @@ } }, "node_modules/@storybook/codemod/node_modules/@babel/preset-env": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz", - "integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", + "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", @@ -9147,7 +8676,7 @@ "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -9168,13 +8697,13 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.4", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", "@babel/plugin-transform-async-to-generator": "^7.23.3", "@babel/plugin-transform-block-scoped-functions": "^7.23.3", "@babel/plugin-transform-block-scoping": "^7.23.4", "@babel/plugin-transform-class-properties": "^7.23.3", "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.5", + "@babel/plugin-transform-classes": "^7.23.8", "@babel/plugin-transform-computed-properties": "^7.23.3", "@babel/plugin-transform-destructuring": "^7.23.3", "@babel/plugin-transform-dotall-regex": "^7.23.3", @@ -9190,7 +8719,7 @@ "@babel/plugin-transform-member-expression-literals": "^7.23.3", "@babel/plugin-transform-modules-amd": "^7.23.3", "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", "@babel/plugin-transform-modules-umd": "^7.23.3", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", "@babel/plugin-transform-new-target": "^7.23.3", @@ -9216,9 +8745,9 @@ "@babel/plugin-transform-unicode-regex": "^7.23.3", "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, @@ -9244,13 +8773,13 @@ } }, "node_modules/@storybook/codemod/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -9262,9 +8791,9 @@ } }, "node_modules/@storybook/codemod/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -9275,9 +8804,9 @@ } }, "node_modules/@storybook/codemod/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -9288,12 +8817,12 @@ } }, "node_modules/@storybook/codemod/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -9303,27 +8832,14 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/codemod/node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", - "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", + "node_modules/@storybook/codemod/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.4", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@storybook/codemod/node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", - "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.4" + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -9354,18 +8870,18 @@ } }, "node_modules/@storybook/components": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.6.4.tgz", - "integrity": "sha512-K5RvEObJAnX+SbGJbkM1qrZEk+VR2cUhRCSrFnlfMwsn8/60T3qoH7U8bCXf8krDgbquhMwqev5WzDB+T1VV8g==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.6.17.tgz", + "integrity": "sha512-lbh7GynMidA+CZcJnstVku6Nhs+YkqjYaZ+mKPugvlVhGVWv0DaaeQFVuZ8cJtUGJ/5FFU4Y+n+gylYUHkGBMA==", "dev": true, "dependencies": { "@radix-ui/react-select": "^1.2.2", "@radix-ui/react-toolbar": "^1.0.4", - "@storybook/client-logger": "7.6.4", + "@storybook/client-logger": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/theming": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/theming": "7.6.17", + "@storybook/types": "7.6.17", "memoizerific": "^1.11.3", "use-resize-observer": "^9.1.0", "util-deprecate": "^1.0.2" @@ -9380,13 +8896,13 @@ } }, "node_modules/@storybook/components/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -9398,9 +8914,9 @@ } }, "node_modules/@storybook/components/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -9411,9 +8927,9 @@ } }, "node_modules/@storybook/components/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -9424,13 +8940,13 @@ } }, "node_modules/@storybook/components/node_modules/@storybook/theming": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.4.tgz", - "integrity": "sha512-Z/dcC5EpkIXelYCkt9ojnX6D7qGOng8YHxV/OWlVE9TrEGYVGPOEfwQryR0RhmGpDha1TYESLYrsDb4A8nJ1EA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.17.tgz", + "integrity": "sha512-ZbaBt3KAbmBtfjNqgMY7wPMBshhSJlhodyMNQypv+95xLD/R+Az6aBYbpVAOygLaUQaQk4ar7H/Ww6lFIoiFbA==", "dev": true, "dependencies": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.6.4", + "@storybook/client-logger": "7.6.17", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" }, @@ -9444,12 +8960,12 @@ } }, "node_modules/@storybook/components/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -9460,14 +8976,14 @@ } }, "node_modules/@storybook/core-common": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.4.tgz", - "integrity": "sha512-qes4+mXqINu0kCgSMFjk++GZokmYjb71esId0zyJsk0pcIPkAiEjnhbSEQkMhbUfcvO1lztoaQTBW2P7Rd1tag==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.17.tgz", + "integrity": "sha512-me2TP3Q9/qzqCLoDHUSsUF+VS1MHxfHbTVF6vAz0D/COTxzsxLpu9TxTbzJoBCxse6XRb6wWI1RgF1mIcjic7g==", "dev": true, "dependencies": { - "@storybook/core-events": "7.6.4", - "@storybook/node-logger": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/core-events": "7.6.17", + "@storybook/node-logger": "7.6.17", + "@storybook/types": "7.6.17", "@types/find-cache-dir": "^3.2.1", "@types/node": "^18.0.0", "@types/node-fetch": "^2.6.4", @@ -9494,366 +9010,14 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/core-common/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@storybook/core-common/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -9865,9 +9029,9 @@ } }, "node_modules/@storybook/core-common/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -9878,9 +9042,9 @@ } }, "node_modules/@storybook/core-common/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -9891,12 +9055,12 @@ } }, "node_modules/@storybook/core-common/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -9915,43 +9079,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/@storybook/core-common/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, "node_modules/@storybook/core-common/node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", @@ -10003,15 +9130,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@storybook/core-common/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/@storybook/core-events": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.2.2.tgz", @@ -10024,26 +9142,26 @@ } }, "node_modules/@storybook/core-server": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.6.4.tgz", - "integrity": "sha512-mXxZMpCwOhjEPPRjqrTHdiCpFdkc47f46vlgTj02SX+9xKHxslmZ2D3JG/8O4Ab9tG+bBl6lBm3RIrIzaiCu9Q==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.6.17.tgz", + "integrity": "sha512-KWGhTTaL1Q14FolcoKKZgytlPJUbH6sbJ1Ptj/84EYWFewcnEgVs0Zlnh1VStRZg+Rd1WC1V4yVd/bbDzxrvQA==", "dev": true, "dependencies": { "@aw-web-design/x-default-browser": "1.4.126", "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "7.6.4", - "@storybook/channels": "7.6.4", - "@storybook/core-common": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/builder-manager": "7.6.17", + "@storybook/channels": "7.6.17", + "@storybook/core-common": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", - "@storybook/csf-tools": "7.6.4", + "@storybook/csf-tools": "7.6.17", "@storybook/docs-mdx": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager": "7.6.4", - "@storybook/node-logger": "7.6.4", - "@storybook/preview-api": "7.6.4", - "@storybook/telemetry": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/manager": "7.6.17", + "@storybook/node-logger": "7.6.17", + "@storybook/preview-api": "7.6.17", + "@storybook/telemetry": "7.6.17", + "@storybook/types": "7.6.17", "@types/detect-port": "^1.3.0", "@types/node": "^18.0.0", "@types/pretty-hrtime": "^1.0.0", @@ -10056,7 +9174,7 @@ "express": "^4.17.3", "fs-extra": "^11.1.0", "globby": "^11.0.2", - "ip": "^2.0.0", + "ip": "^2.0.1", "lodash": "^4.17.21", "open": "^8.4.0", "pretty-hrtime": "^1.0.3", @@ -10077,13 +9195,13 @@ } }, "node_modules/@storybook/core-server/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -10095,9 +9213,9 @@ } }, "node_modules/@storybook/core-server/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -10108,9 +9226,9 @@ } }, "node_modules/@storybook/core-server/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -10121,17 +9239,17 @@ } }, "node_modules/@storybook/core-server/node_modules/@storybook/preview-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.4.tgz", - "integrity": "sha512-KhisNdQX5NdfAln+spLU4B82d804GJQp/CnI5M1mm/taTnjvMgs/wTH9AmR89OPoq+tFZVW0vhy2zgPS3ar71A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", + "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -10147,12 +9265,12 @@ } }, "node_modules/@storybook/core-server/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -10177,9 +9295,9 @@ } }, "node_modules/@storybook/core-server/node_modules/ws": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.0.tgz", - "integrity": "sha512-H/Z3H55mrcrgjFwI+5jKavgXvwQLtfPCUEp6pi35VhoB0pfcHnSoyuTzkBEZpzq49g1193CUEwIvmsjcotenYw==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -10198,14 +9316,14 @@ } }, "node_modules/@storybook/core-webpack": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-7.6.4.tgz", - "integrity": "sha512-+C2YddhOhO0Lp9KngzX9XYJZKzCzo4vjXA3IMXxSA7Vo7gFhaa8uQTAXnUx7xCrvFXM/iiHUY1SN+VppB0eBdA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-7.6.17.tgz", + "integrity": "sha512-PyGrFhRM8sTONGwwLWLqBQ1HO+LBnVZ+5TOQO7ejQfdV2FWyNOzjBXm2e5jL/C6XlqiEhmL5pyHEyDBaQJQ3KA==", "dev": true, "dependencies": { - "@storybook/core-common": "7.6.4", - "@storybook/node-logger": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/core-common": "7.6.17", + "@storybook/node-logger": "7.6.17", + "@storybook/types": "7.6.17", "@types/node": "^18.0.0", "ts-dedent": "^2.0.0" }, @@ -10215,13 +9333,13 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -10233,9 +9351,9 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -10246,9 +9364,9 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -10259,12 +9377,12 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -10284,12 +9402,12 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.6.4.tgz", - "integrity": "sha512-7g9p8s2ITX+Z9iThK5CehPhJOcusVN7JcUEEW+gVF5PlYT+uk/x+66gmQno+scQuNkV9+8UJD6RLFjP+zg2uCA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.6.17.tgz", + "integrity": "sha512-xTHv9BUh3bkDVCvcbmdfVF0/e96BdrEgqPJ3G3RmKbSzWLOkQ2U9yiPfHzT0KJWPhVwj12fjfZp0zunu+pcS6Q==", "dev": true, "dependencies": { - "@storybook/csf-tools": "7.6.4", + "@storybook/csf-tools": "7.6.17", "unplugin": "^1.3.1" }, "funding": { @@ -10298,9 +9416,9 @@ } }, "node_modules/@storybook/csf-tools": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.4.tgz", - "integrity": "sha512-6sLayuhgReIK3/QauNj5BW4o4ZfEMJmKf+EWANPEM/xEOXXqrog6Un8sjtBuJS9N1DwyhHY6xfkEiPAwdttwqw==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.17.tgz", + "integrity": "sha512-dAQtam0EBPeTJYcQPLxXgz4L9JFqD+HWbLFG9CmNIhMMjticrB0mpk1EFIS6vPXk/VsVWpBgMLD7dZlD6YMKcQ==", "dev": true, "dependencies": { "@babel/generator": "^7.23.0", @@ -10308,7 +9426,7 @@ "@babel/traverse": "^7.23.2", "@babel/types": "^7.23.0", "@storybook/csf": "^0.1.2", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "fs-extra": "^11.1.0", "recast": "^0.23.1", "ts-dedent": "^2.0.0" @@ -10334,13 +9452,13 @@ } }, "node_modules/@storybook/csf-tools/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -10352,9 +9470,9 @@ } }, "node_modules/@storybook/csf-tools/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -10365,9 +9483,9 @@ } }, "node_modules/@storybook/csf-tools/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -10378,12 +9496,12 @@ } }, "node_modules/@storybook/csf-tools/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -10414,14 +9532,14 @@ "dev": true }, "node_modules/@storybook/docs-tools": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.6.4.tgz", - "integrity": "sha512-2eGam43aD7O3cocA72Z63kRi7t/ziMSpst0qB218QwBWAeZjT4EYDh8V6j/Xhv6zVQL3msW7AglrQP5kCKPvPA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.6.17.tgz", + "integrity": "sha512-bYrLoj06adqklyLkEwD32C0Ww6t+9ZVvrJHiVT42bIhTRpFiFPAetl1a9KPHtFLnfduh4n2IxIr1jv32ThPDTA==", "dev": true, "dependencies": { - "@storybook/core-common": "7.6.4", - "@storybook/preview-api": "7.6.4", - "@storybook/types": "7.6.4", + "@storybook/core-common": "7.6.17", + "@storybook/preview-api": "7.6.17", + "@storybook/types": "7.6.17", "@types/doctrine": "^0.0.3", "assert": "^2.1.0", "doctrine": "^3.0.0", @@ -10433,13 +9551,13 @@ } }, "node_modules/@storybook/docs-tools/node_modules/@storybook/channels": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.4.tgz", - "integrity": "sha512-Z4PY09/Czl70ap4ObmZ4bgin+EQhPaA3HdrEDNwpnH7A9ttfEO5u5KThytIjMq6kApCCihmEPDaYltoVrfYJJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", + "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.2.0", @@ -10451,9 +9569,9 @@ } }, "node_modules/@storybook/docs-tools/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -10464,9 +9582,9 @@ } }, "node_modules/@storybook/docs-tools/node_modules/@storybook/core-events": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.4.tgz", - "integrity": "sha512-i3xzcJ19ILSy4oJL5Dz9y0IlyApynn5RsGhAMIsW+mcfri+hGfeakq1stNCo0o7jW4Y3A7oluFTtIoK8DOxQdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", + "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -10477,17 +9595,17 @@ } }, "node_modules/@storybook/docs-tools/node_modules/@storybook/preview-api": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.4.tgz", - "integrity": "sha512-KhisNdQX5NdfAln+spLU4B82d804GJQp/CnI5M1mm/taTnjvMgs/wTH9AmR89OPoq+tFZVW0vhy2zgPS3ar71A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", + "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", - "@storybook/client-logger": "7.6.4", - "@storybook/core-events": "7.6.4", + "@storybook/channels": "7.6.17", + "@storybook/client-logger": "7.6.17", + "@storybook/core-events": "7.6.17", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.4", + "@storybook/types": "7.6.17", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -10503,12 +9621,12 @@ } }, "node_modules/@storybook/docs-tools/node_modules/@storybook/types": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.4.tgz", - "integrity": "sha512-qyiiXPCvol5uVgfubcIMzJBA0awAyFPU+TyUP1mkPYyiTHnsHYel/mKlSdPjc8a97N3SlJXHOCx41Hde4IyJgg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", + "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", "dev": true, "dependencies": { - "@storybook/channels": "7.6.4", + "@storybook/channels": "7.6.17", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" @@ -10790,9 +9908,9 @@ } }, "node_modules/@storybook/manager": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.6.4.tgz", - "integrity": "sha512-Ug2ejfKgKre8h/RJbkumukwAA44TbvTPEjDcJmyFdAI+kHYhOYdKPEC2UNmVYz8/4HjwMTJQ3M7t/esK8HHY4A==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.6.17.tgz", + "integrity": "sha512-A1LDDIqMpwRzq/dqkbbiza0QI04o4ZHCl2a3UMDZUV/+QLc2nsr2DAaLk4CVL4/cIc5zGqmIcaOTvprx2YKVBw==", "dev": true, "funding": { "type": "opencollective", @@ -10838,9 +9956,9 @@ "dev": true }, "node_modules/@storybook/node-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.4.tgz", - "integrity": "sha512-GDkEnnDj4Op+PExs8ZY/P6ox3wg453CdEIaR8PR9TxF/H/T2fBL6puzma3hN2CMam6yzfAL8U+VeIIDLQ5BZdQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.17.tgz", + "integrity": "sha512-w59MQuXhhUNrUVmVkXhMwIg2nvFWjdDczLTwYLorhfsE36CWeUOY5QCZWQy0Qf/h+jz8Uo7Evy64qn18v9C4wA==", "dev": true, "funding": { "type": "opencollective", @@ -10848,9 +9966,9 @@ } }, "node_modules/@storybook/postinstall": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.6.4.tgz", - "integrity": "sha512-7uoB82hSzlFSdDMS3hKQD+AaeSvPit/fAMvXCBxn0/D0UGJUZcq4M9JcKBwEHkZJcbuDROgOTJ6TUeXi/FWO0w==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.6.17.tgz", + "integrity": "sha512-WaWqB8o9vUc9aaVls+povQSVirf1Xd1LZcVhUKfAocAF3mzYUsnJsVqvnbjRj/F96UFVihOyDt9Zjl/9OvrCvQ==", "dev": true, "funding": { "type": "opencollective", @@ -10858,9 +9976,9 @@ } }, "node_modules/@storybook/preview": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.6.4.tgz", - "integrity": "sha512-p9xIvNkgXgTpSRphOMV9KpIiNdkymH61jBg3B0XyoF6IfM1S2/mQGvC89lCVz1dMGk2SrH4g87/WcOapkU5ArA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.6.17.tgz", + "integrity": "sha512-LvkMYK/y6alGjwRVNDIKL1lFlbyZ0H0c8iAbcQkiMoaFiujMQyVswMDKlWcj42Upfr/B1igydiruomc+eUt0mw==", "dev": true, "funding": { "type": "opencollective", @@ -10895,9 +10013,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.6.4.tgz", - "integrity": "sha512-wGJfomlDEBnowNmhmumWDu/AcUInxSoPqUUJPgk2f5oL0EW17fR9fDP/juG3XOEdieMDM0jDX48GML7lyvL2fg==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.6.17.tgz", + "integrity": "sha512-32Sa/G+WnvaPiQ1Wvjjw5UM9rr2c4GDohwCcWVv3/LJuiFPqNS6zglAtmnsrlIBnUwRBMLMh/ekCTdqMiUmfDw==", "dev": true, "funding": { "type": "opencollective", @@ -10929,14 +10047,14 @@ } }, "node_modules/@storybook/telemetry": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.6.4.tgz", - "integrity": "sha512-Q4QpvcgloHUEqC9PGo7tgqkUH91/PjX+74/0Hi9orLo8QmLMgdYS5fweFwgSKoTwDGNg2PaHp/jqvhhw7UmnJA==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.6.17.tgz", + "integrity": "sha512-WOcOAmmengYnGInH98Px44F47DSpLyk20BM+Z/IIQDzfttGOLlxNqBBG1XTEhNRn+AYuk4aZ2JEed2lCjVIxcA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.6.4", - "@storybook/core-common": "7.6.4", - "@storybook/csf-tools": "7.6.4", + "@storybook/client-logger": "7.6.17", + "@storybook/core-common": "7.6.17", + "@storybook/csf-tools": "7.6.17", "chalk": "^4.1.0", "detect-package-manager": "^2.0.1", "fetch-retry": "^5.0.2", @@ -10949,9 +10067,9 @@ } }, "node_modules/@storybook/telemetry/node_modules/@storybook/client-logger": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.4.tgz", - "integrity": "sha512-vJwMShC98tcoFruRVQ4FphmFqvAZX1FqZqjFyk6IxtFumPKTVSnXJjlU1SnUIkSK2x97rgdUMqkdI+wAv/tugQ==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", + "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -13657,9 +12775,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -15636,9 +14754,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "funding": [ { "type": "opencollective", @@ -15647,13 +14765,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -16088,9 +15210,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001565", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", - "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", + "version": "1.0.30001588", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", + "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", "funding": [ { "type": "opencollective", @@ -16293,11 +15415,10 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true, - "peer": true + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true }, "node_modules/class-utils": { "version": "0.3.6", @@ -17263,50 +16384,18 @@ } }, "node_modules/core-js-compat": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", - "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", "dev": true, "dependencies": { - "browserslist": "^4.22.1" + "browserslist": "^4.22.3" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, - "node_modules/core-js-compat/node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -18678,9 +17767,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.611", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.611.tgz", - "integrity": "sha512-ZtRpDxrjHapOwxtv+nuth5ByB8clyn8crVynmRNGO3wG3LOp8RTcyZDqwaI6Ng6y8FCK2hVZmJoqwCskKbNMaw==" + "version": "1.4.676", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.676.tgz", + "integrity": "sha512-uHt4FB8SeYdhcOsj2ix/C39S7sPSNFJpzShjxGOm1KdF4MHyGqGi389+T5cErsodsijojXilYaHIKKqJfqh7uQ==" }, "node_modules/electron-updater": { "version": "6.1.8", @@ -23816,9 +22905,9 @@ } }, "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", "dev": true }, "node_modules/ipaddr.js": { @@ -27682,9 +26771,9 @@ } }, "node_modules/markdown-to-jsx": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz", - "integrity": "sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.4.1.tgz", + "integrity": "sha512-GbrbkTnHp9u6+HqbPRFJbObi369AgJNXi/sGqq5HRsoZW063xR1XDCaConqq+whfEIAlzB1YPnOgsPc7B7bc/A==", "dev": true, "engines": { "node": ">= 10" @@ -35637,12 +34726,12 @@ "dev": true }, "node_modules/storybook": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.6.4.tgz", - "integrity": "sha512-nQhs9XkrroxjqMoBnnToyc6M8ndbmpkOb1qmULO4chtfMy4k0p9Un3K4TJvDaP8c3wPUFGd4ZaJ1hZNVmIl56Q==", + "version": "7.6.17", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.6.17.tgz", + "integrity": "sha512-8+EIo91bwmeFWPg1eysrxXlhIYv3OsXrznTr4+4Eq0NikqAoq6oBhtlN5K2RGS2lBVF537eN+9jTCNbR+WrzDA==", "dev": true, "dependencies": { - "@storybook/cli": "7.6.4" + "@storybook/cli": "7.6.17" }, "bin": { "sb": "index.js", @@ -36879,9 +35968,9 @@ } }, "node_modules/tocbot": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/tocbot/-/tocbot-4.23.0.tgz", - "integrity": "sha512-5DWuSZXsqG894mkGb8ZsQt9myyQyVxE50AiGRZ0obV0BVUTVkaZmc9jbgpknaAAPUm4FIrzGkEseD6FuQJYJDQ==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/tocbot/-/tocbot-4.25.0.tgz", + "integrity": "sha512-kE5wyCQJ40hqUaRVkyQ4z5+4juzYsv/eK+aqD97N62YH0TxFhzJvo22RUQQZdO3YnXAk42ZOfOpjVdy+Z0YokA==", "dev": true }, "node_modules/toidentifier": { @@ -37763,15 +36852,15 @@ } }, "node_modules/unplugin": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.5.1.tgz", - "integrity": "sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.7.1.tgz", + "integrity": "sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw==", "dev": true, "dependencies": { - "acorn": "^8.11.2", + "acorn": "^8.11.3", "chokidar": "^3.5.3", "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.6.0" + "webpack-virtual-modules": "^0.6.1" } }, "node_modules/unplugin/node_modules/webpack-virtual-modules": { diff --git a/package.json b/package.json index f8b6964bc6a..0f15610a860 100644 --- a/package.json +++ b/package.json @@ -45,13 +45,13 @@ "@electron/notarize": "2.3.0", "@electron/rebuild": "3.6.0", "@ngtools/webpack": "16.2.11", - "@storybook/addon-a11y": "7.6.4", - "@storybook/addon-actions": "7.6.4", + "@storybook/addon-a11y": "7.6.17", + "@storybook/addon-actions": "7.6.17", "@storybook/addon-designs": "7.0.7", - "@storybook/addon-essentials": "7.6.4", - "@storybook/addon-interactions": "7.6.4", - "@storybook/addon-links": "7.6.4", - "@storybook/angular": "7.6.4", + "@storybook/addon-essentials": "7.6.17", + "@storybook/addon-interactions": "7.6.17", + "@storybook/addon-links": "7.6.17", + "@storybook/angular": "7.6.17", "@storybook/jest": "0.2.3", "@storybook/testing-library": "0.2.2", "@types/argon2-browser": "1.18.1", @@ -132,7 +132,7 @@ "rimraf": "5.0.5", "sass": "1.69.5", "sass-loader": "13.3.2", - "storybook": "7.6.4", + "storybook": "7.6.17", "style-loader": "3.3.3", "tailwindcss": "3.3.5", "ts-jest": "29.1.2", From 0f9a9dcbf641bfb61a281ffa7012c360bc03908d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 12:06:10 +0000 Subject: [PATCH 002/124] Autosync the updated translations (#8061) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 3 + apps/web/src/locales/ar/messages.json | 3 + apps/web/src/locales/az/messages.json | 3 + apps/web/src/locales/be/messages.json | 3 + apps/web/src/locales/bg/messages.json | 3 + apps/web/src/locales/bn/messages.json | 3 + apps/web/src/locales/bs/messages.json | 3 + apps/web/src/locales/ca/messages.json | 3 + apps/web/src/locales/cs/messages.json | 3 + apps/web/src/locales/cy/messages.json | 3 + apps/web/src/locales/da/messages.json | 5 +- apps/web/src/locales/de/messages.json | 3 + apps/web/src/locales/el/messages.json | 3 + apps/web/src/locales/en_GB/messages.json | 3 + apps/web/src/locales/en_IN/messages.json | 3 + apps/web/src/locales/eo/messages.json | 3 + apps/web/src/locales/es/messages.json | 103 +++++++------- apps/web/src/locales/et/messages.json | 3 + apps/web/src/locales/eu/messages.json | 3 + apps/web/src/locales/fa/messages.json | 3 + apps/web/src/locales/fi/messages.json | 173 ++++++++++++----------- apps/web/src/locales/fil/messages.json | 3 + apps/web/src/locales/fr/messages.json | 3 + apps/web/src/locales/gl/messages.json | 3 + apps/web/src/locales/he/messages.json | 3 + apps/web/src/locales/hi/messages.json | 3 + apps/web/src/locales/hr/messages.json | 3 + apps/web/src/locales/hu/messages.json | 3 + apps/web/src/locales/id/messages.json | 3 + apps/web/src/locales/it/messages.json | 3 + apps/web/src/locales/ja/messages.json | 3 + apps/web/src/locales/ka/messages.json | 3 + apps/web/src/locales/km/messages.json | 3 + apps/web/src/locales/kn/messages.json | 3 + apps/web/src/locales/ko/messages.json | 3 + apps/web/src/locales/lv/messages.json | 3 + apps/web/src/locales/ml/messages.json | 3 + apps/web/src/locales/mr/messages.json | 3 + apps/web/src/locales/my/messages.json | 3 + apps/web/src/locales/nb/messages.json | 3 + apps/web/src/locales/ne/messages.json | 3 + apps/web/src/locales/nl/messages.json | 3 + apps/web/src/locales/nn/messages.json | 3 + apps/web/src/locales/or/messages.json | 3 + apps/web/src/locales/pl/messages.json | 3 + apps/web/src/locales/pt_BR/messages.json | 71 +++++----- apps/web/src/locales/pt_PT/messages.json | 3 + apps/web/src/locales/ro/messages.json | 3 + apps/web/src/locales/ru/messages.json | 13 +- apps/web/src/locales/si/messages.json | 3 + apps/web/src/locales/sk/messages.json | 3 + apps/web/src/locales/sl/messages.json | 3 + apps/web/src/locales/sr/messages.json | 3 + apps/web/src/locales/sr_CS/messages.json | 3 + apps/web/src/locales/sv/messages.json | 3 + apps/web/src/locales/te/messages.json | 3 + apps/web/src/locales/th/messages.json | 3 + apps/web/src/locales/tr/messages.json | 3 + apps/web/src/locales/uk/messages.json | 3 + apps/web/src/locales/vi/messages.json | 3 + apps/web/src/locales/zh_CN/messages.json | 17 ++- apps/web/src/locales/zh_TW/messages.json | 3 + 62 files changed, 368 insertions(+), 182 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index ad5450cef41..f54d86367f3 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 35bc666a335..b25b1e25ddc 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index ad06079abc3..eb989be5eb8 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Çox bahadır", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index cc6a8580d1c..4ec488e9fdc 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 398efc33ffb..52741ea34a0 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Твърде скъпо", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index c8cf3ec2a0d..cb4e8386a51 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 5d7e3fa0780..e9031507be3 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 23ae03f0e74..2fc12b6efcd 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Massa car", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index 3f1d9f99211..8706e059a45 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Příliš drahé", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Zdarma na 1 rok" } } diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index 62e8445b541..ee27c6d65ad 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index 2000273a132..47c1301538d 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -6009,7 +6009,7 @@ "message": "-- Vælg --" }, "multiSelectPlaceholder": { - "message": "-- Skriv for at filtrere --" + "message": "-- Filtreringstype --" }, "multiSelectLoading": { "message": "Henter indstillinger..." @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "For dyrt", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 8aa89ac427b..6b4b9d14d1a 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Zu teuer", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index 47435bd9074..b25fe05122e 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 642574ecef2..1a3f4c693b6 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index b766347dc68..c13badafaab 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index f302f65a623..a6111645aa4 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 6dd50dafd4b..cc039cae62f 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -675,10 +675,10 @@ "message": "Se utiliza para el cifrado" }, "loginWithPasskeyEnabled": { - "message": "Log in with passkey turned on" + "message": "Iniciar sesión con la clave activada" }, "passkeySaved": { - "message": "$NAME$ saved", + "message": "$NAME$ guardado", "placeholders": { "name": { "content": "$1", @@ -687,19 +687,19 @@ } }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Clave eliminada" }, "removePasskey": { - "message": "Remove passkey" + "message": "Eliminar clave" }, "removePasskeyInfo": { - "message": "If all passkeys are removed, you will be unable to log into new devices without your master password." + "message": "Si se eliminan todas las claves, no podrá iniciar sesión en nuevos dispositivos sin su contraseña maestra." }, "passkeyLimitReachedInfo": { - "message": "Passkey limit reached. Remove a passkey to add another." + "message": "Límite de clave alcanzado. Elimine una clave para añadir otra." }, "tryAgain": { - "message": "Try again" + "message": "Inténtelo de nuevo" }, "createAccount": { "message": "Crear cuenta" @@ -799,7 +799,7 @@ "message": "Ha ocurrido un error inesperado." }, "expirationDateError": { - "message": "Please select an expiration date that is in the future." + "message": "Seleccione una fecha de caducidad futura." }, "emailAddress": { "message": "Correo electrónico" @@ -1042,7 +1042,7 @@ "message": "Copiar código de verificación" }, "copyUuid": { - "message": "Copy UUID" + "message": "Copiar UUID" }, "warning": { "message": "Advertencia" @@ -1069,7 +1069,7 @@ "message": "Exportar" }, "exportFrom": { - "message": "Export from" + "message": "Exportar desde" }, "exportVault": { "message": "Exportar caja fuerte" @@ -1148,7 +1148,7 @@ "message": "Longitud" }, "passwordMinLength": { - "message": "Minimum password length" + "message": "Longitud mínima de la contraseña" }, "uppercase": { "message": "Mayúsculas (A-Z)", @@ -1348,15 +1348,15 @@ "message": "Importar datos" }, "onboardingImportDataDetailsPartOne": { - "message": "If you don't have any data to import, you can create a ", + "message": "Si no tiene ningún dato para importar, puede crear un ", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "onboardingImportDataDetailsLink": { - "message": "new item", + "message": "nuevo elemento", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "onboardingImportDataDetailsPartTwo": { - "message": " instead. You may need to wait until your administrator confirms your organization membership.", + "message": " en su lugar. Puede que tenga que esperar hasta que su administrador confirme la pertenencia a su organización.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "importError": { @@ -1399,19 +1399,19 @@ "message": "Error al descifrar el archivo exportado. Su clave de cifrado no coincide con la clave de cifrado utilizada para exporta los datos." }, "importDestination": { - "message": "Import destination" + "message": "Importar destino" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "Conozca sus opciones de importación" }, "selectImportFolder": { - "message": "Select a folder" + "message": "Seleccione una carpeta" }, "selectImportCollection": { - "message": "Select a collection" + "message": "Seleccione una colección" }, "importTargetHint": { - "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", + "message": "Seleccione esta opción si desea que el contenido del archivo importado se traslade a un $DESTINATION$", "description": "Located as a hint under the import target. Will be appended by either folder or collection, depending if the user is importing into an individual or an organizational vault.", "placeholders": { "destination": { @@ -1421,7 +1421,7 @@ } }, "importUnassignedItemsError": { - "message": "File contains unassigned items." + "message": "El archivo contiene elementos no asignados." }, "selectFormat": { "message": "Selecciona el formato del fichero a importar" @@ -1531,10 +1531,10 @@ "message": "Protege tu cuenta requiriendo un paso adicional a la hora de acceder." }, "twoStepLoginTeamsDesc": { - "message": "Enable two-step login for your organization." + "message": "Active el inicio de sesión en dos pasos para su organización." }, "twoStepLoginEnterpriseDescStart": { - "message": "Enforce Bitwarden Two-step Login options for members by using the ", + "message": "Aplique las opciones de inicio de sesión en dos pasos de Bitwarden para los miembros mediante ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Enforce Bitwarden Two-step Login options for members by using the Two-step Login Policy.'" }, "twoStepLoginPolicy": { @@ -1588,7 +1588,7 @@ "message": "Gestionar" }, "canManage": { - "message": "Can manage" + "message": "Puede gestionar" }, "disable": { "message": "Desactivar" @@ -2152,7 +2152,7 @@ } }, "paymentChargedWithUnpaidSubscription": { - "message": "Your payment method will be charged for any unpaid subscriptions." + "message": "Las suscripciones impagadas se cargarán a su método de pago." }, "paymentChargedWithTrial": { "message": "Your plan comes with a free 7 day trial. Your card will not be charged until the trial has ended and on a recurring basis each $INTERVAL$. You may cancel at any time." @@ -2323,7 +2323,7 @@ "message": "Póngase en contacto con el servicio de atención al cliente" }, "contactSupportShort": { - "message": "Contact Support" + "message": "Contactar con soporte técnico" }, "updatedPaymentMethod": { "message": "Método de pago actualizado." @@ -2541,7 +2541,7 @@ } }, "trialSecretsManagerThankYou": { - "message": "Thanks for signing up for Bitwarden Secrets Manager for $PLAN$!", + "message": "¡Gracias por suscribirse a Bitwarden Secrets Manager por $PLAN$!", "placeholders": { "plan": { "content": "$1", @@ -2835,7 +2835,7 @@ "message": "Código incorrecto" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "PIN incorrecto" }, "exportedVault": { "message": "Caja fuerte exportada." @@ -3528,7 +3528,7 @@ "message": "Suscripción actualizada" }, "subscribedToSecretsManager": { - "message": "Subscription updated. You now have access to Secrets Manager." + "message": "Suscripción actualizada. Ahora tiene acceso al Gestor de Secretos." }, "additionalOptions": { "message": "Opciones adicionales" @@ -3549,7 +3549,7 @@ } }, "subscriptionUserSeatsWithoutAdditionalSeatsOption": { - "message": "You can invite up to $COUNT$ members for no additional charge. Contact Customer Support to upgrade your plan and invite more members.", + "message": "Puede invitar hasta $COUNT$ miembros sin cargo adicional. Póngase en contacto con el servicio de atención al cliente para actualizar su plan e invitar a más miembros.", "placeholders": { "count": { "content": "$1", @@ -3567,7 +3567,7 @@ } }, "subscriptionUpgrade": { - "message": "You cannot invite more than $COUNT$ members without upgrading your plan.", + "message": "No puede invitar a más de $COUNT$ miembros sin actualizar su plan.", "placeholders": { "count": { "content": "$1", @@ -3717,16 +3717,16 @@ "message": "La organización está desactivada." }, "secretsAccessSuspended": { - "message": "Suspended organizations cannot be accessed. Please contact your organization owner for assistance." + "message": "No se puede acceder a las organizaciones suspendidas. Póngase en contacto con el propietario de su organización para obtener ayuda." }, "secretsCannotCreate": { - "message": "Secrets cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "No se pueden crear secretos en organizaciones suspendidas. Póngase en contacto con el propietario de su organización para obtener ayuda." }, "projectsCannotCreate": { - "message": "Projects cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "No se pueden crear proyectos en organizaciones suspendidas. Póngase en contacto con el propietario de su organización para obtener ayuda." }, "serviceAccountsCannotCreate": { - "message": "Service accounts cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "No se pueden crear cuentas de servicio en organizaciones suspendidas. Póngase en contacto con el propietario de su organización para obtener ayuda." }, "disabledOrganizationFilterError": { "message": "No se puede acceder a los elementos que pertenecen a organizaciones que estén deshabilitadas. Por favor, póngase en contacto con el propietario de la organización para obtener ayuda." @@ -3781,7 +3781,7 @@ "message": "Este elemento tiene archivos adjuntos antiguos que deben ser corregidos." }, "attachmentFixDescription": { - "message": "This attachment uses outdated encryption. Select 'Fix' to download, re-encrypt, and re-upload the attachment." + "message": "Este archivo adjunto utiliza un cifrado obsoleto. Seleccione \"Corregir\" para descargar, volver a cifrar y volver a cargar el archivo adjunto." }, "fix": { "message": "Arreglar", @@ -4044,22 +4044,22 @@ "message": "Ya puedes cerrar esta pestaña y continuar en la extensión." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Ha iniciado sesión correctamente" }, "thisWindowWillCloseIn5Seconds": { - "message": "This window will automatically close in 5 seconds" + "message": "Esta ventana se cerrará automáticamente en 5 segundos" }, "includeAllTeamsFeatures": { "message": "Todas las características de Equipos y además:" }, "includeAllTeamsStarterFeatures": { - "message": "All Teams Starter features, plus:" + "message": "Todas las características de Teams Starter, y además:" }, "chooseMonthlyOrAnnualBilling": { - "message": "Choose monthly or annual billing" + "message": "Facturación mensual o anual" }, "abilityToAddMoreThanNMembers": { - "message": "Ability to add more than $COUNT$ members", + "message": "Posibilidad de añadir más de $COUNT$ miembros", "placeholders": { "count": { "content": "$1", @@ -4083,7 +4083,7 @@ "message": "Identificador SSO" }, "ssoIdentifierHintPartOne": { - "message": "Provide this ID to your members to login with SSO. To bypass this step, set up ", + "message": "Proporcione este ID a sus miembros para iniciar sesión con SSO. Para evitar este paso, configure ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Provide this ID to your members to login with SSO. To bypass this step, set up Domain verification'" }, "unlinkSso": { @@ -4255,7 +4255,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "downloadAttachments": { - "message": "Download attachments" + "message": "Descargar archivos adjuntos" }, "sendAccessUnavailable": { "message": "El envío al que está intentando acceder no existe o ya no está disponible.", @@ -4646,7 +4646,7 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more about Bitwarden Send or sign up to **try it today.**'" }, "sendAccessCreatorIdentifier": { - "message": "Bitwarden member $USER_IDENTIFIER$ shared the following with you", + "message": "El miembro de Bitwarden $USER_IDENTIFIER$ ha compartido con ustedes lo siguiente", "placeholders": { "user_identifier": { "content": "$1", @@ -4776,13 +4776,13 @@ "message": "Administración de recuperación de cuenta" }, "accountRecoveryPolicyDesc": { - "message": "Based on the encryption method, recover accounts when master passwords or trusted devices are forgotten or lost." + "message": "Basándose en el método de cifrado, recupere las cuentas cuando se olviden o pierdan las contraseñas maestras o los dispositivos de confianza." }, "accountRecoveryPolicyWarning": { - "message": "Existing accounts with master passwords will require members to self-enroll before administrators can recover their accounts. Automatic enrollment will turn on account recovery for new members." + "message": "Las cuentas existentes con contraseñas maestras requerirán que los miembros se autoinscriban antes de que los administradores puedan recuperar sus cuentas. La inscripción automática activará la recuperación de cuentas para los nuevos miembros." }, "accountRecoverySingleOrgRequirementDesc": { - "message": "The single organization Enterprise policy must be turned on before activating this policy." + "message": "La política de empresa de organización única debe estar activada antes de activar esta política." }, "resetPasswordPolicyAutoEnroll": { "message": "Inscripción automática" @@ -7372,7 +7372,7 @@ "message": "Additional service accounts" }, "includedServiceAccounts": { - "message": "Your plan comes with $COUNT$ service accounts.", + "message": "Su plan incluye $COUNT$ cuentas de servicio.", "placeholders": { "count": { "content": "$1", @@ -7381,7 +7381,7 @@ } }, "addAdditionalServiceAccounts": { - "message": "You can add additional service accounts for $COST$ per month.", + "message": "Puede añadir cuentas de servicio adicionales por $COST$ al mes.", "placeholders": { "cost": { "content": "$1", @@ -7390,10 +7390,10 @@ } }, "collectionManagement": { - "message": "Collection management" + "message": "Gestión de colecciones" }, "collectionManagementDesc": { - "message": "Manage the collection behavior for the organization" + "message": "Administrar el comportamiento de la colección para la organización" }, "limitCollectionCreationDeletionDesc": { "message": "Limit collection creation and deletion to owners and admins" @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index af042167eee..a54f52e5446 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index 57cf263e017..2a9af967155 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index 90d3e4330db..0518b5b30be 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 77f5bc705b6..58f910f48cd 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -732,7 +732,7 @@ "message": "Pääsalasana" }, "masterPassDesc": { - "message": "Pääsalasanalla pääset käsiksi holviisi. On erittäin tärkeää, että muistat pääsalasanasi, koska sen palautus ei ole mahdollista, jos unohdat sen." + "message": "Pääsalasanalla avaat holviisi ja on erittäin tärkeää, että muistat pääsalasanasi, koska sitä ei ole mahdollista palauttaa sen unohtuessa." }, "masterPassImportant": { "message": "Pääsalasanasi palauttaminen ei ole mahdollista, jos unohdat sen!" @@ -836,25 +836,25 @@ "message": "Lukitse nyt" }, "noItemsInList": { - "message": "Ei näytettäviä kohteita." + "message": "Näytettäviä kohteita ei ole." }, "noPermissionToViewAllCollectionItems": { "message": "Sinulla ei ole kokoelman kaikkien kohteiden tarkastelun sallivia käyttöoikeuksia." }, "noCollectionsInList": { - "message": "Ei näytettäviä kokoelmia." + "message": "Näytettäviä kokoelmia ei ole." }, "noGroupsInList": { - "message": "Ei näytettäviä ryhmiä." + "message": "Näytettäviä ryhmiä ei ole." }, "noUsersInList": { - "message": "Ei näytettäviä käyttäjiä." + "message": "Näytettäviä käyttäjiä ei ole." }, "noMembersInList": { "message": "Näytettäviä jäseniä ei ole." }, "noEventsInList": { - "message": "Ei näytettäviä tapahtumia." + "message": "Näytettäviä tapahtumia ei ole." }, "newOrganization": { "message": "Uusi organisaatio" @@ -1181,7 +1181,7 @@ "message": "Salasanahistoria" }, "noPasswordsInList": { - "message": "Ei näytettäviä salasanoja." + "message": "Näytettäviä salasanoja ei ole." }, "clear": { "message": "Tyhjennä", @@ -2742,7 +2742,7 @@ "message": "Omistaja" }, "ownerDesc": { - "message": "Hallitse organisaatiotasi kokonaisvaltaisesti, laskutus ja tilaukset mukaan lukien." + "message": "Voi hallita organisaatiota kokonaisvaltaisesti, laskutus ja tilaukset mukaan lukien." }, "clientOwnerDesc": { "message": "Tämän käyttäjän on oltava toimittajariippumaton. Jos toimittajan yhteys organisaatioon katkaistaan, säilyttää tämä käyttäjä organisaation omistajuuden." @@ -2751,19 +2751,19 @@ "message": "Ylläpitäjä" }, "adminDesc": { - "message": "Hallitse organisaation käyttöoikeuksia, kaikkia kokoelmia, jäseniä, raportointia ja suojausasetuksia." + "message": "Voi hallita organisaation käyttöoikeuksia, kaikkia kokoelmia, jäseniä, raportointia ja suojausasetuksia." }, "user": { "message": "Käyttäjä" }, "userDesc": { - "message": "Käytä ja lisää määritettyjen kokoelmien kohteita." + "message": "Voi käyttää määritettyjen kokoelmien kohteita ja lisätä niitä." }, "manager": { "message": "Valvoja" }, "managerDesc": { - "message": "Luo, poista ja hallitse määritettyjen kokoelmien käyttöoikeuksia." + "message": "Voi luoda, poistaa ja hallita määritettyjen kokoelmien käyttöoikeuksia." }, "all": { "message": "Kaikki" @@ -2772,7 +2772,7 @@ "message": "Päivitä" }, "timestamp": { - "message": "Aikaleima" + "message": "Tapahtuma-aika" }, "event": { "message": "Tapahtuma" @@ -2808,7 +2808,7 @@ "message": "Bitwarden Salaisuushallinta" }, "loggedIn": { - "message": "Kirjautui sisään" + "message": "Kirjautui sisään." }, "changedPassword": { "message": "Tilin salasana vaihdettiin" @@ -2826,7 +2826,7 @@ "message": "Sisäänkirjautumisyritys epäonnistui väärän salasanan vuoksi." }, "failedLogin2fa": { - "message": "Kirjautuminen epäonnistui virheellisen kaksivaiheisen kirjautumisen todennuksen vuoksi." + "message": "Kirjautuminen epäonnistui virheellisen toisen vaiheen vahvistuksen vuoksi." }, "incorrectPassword": { "message": "Virheellinen salasana" @@ -2841,13 +2841,13 @@ "message": "Holvi vietiin" }, "exportedOrganizationVault": { - "message": "Organisaation holvi vietiin." + "message": "Vei organisaation holvin." }, "editedOrgSettings": { "message": "Organisaation asetuksia muokattiin." }, "createdItemId": { - "message": "Kohde $ID$ luotu.", + "message": "Loi kohteen \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -2856,7 +2856,7 @@ } }, "editedItemId": { - "message": "Muokattiin kohdetta $ID$.", + "message": "Muokkasi kohdetta \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -2865,7 +2865,7 @@ } }, "deletedItemId": { - "message": "Sirrettiin kohde $ID$ roskakoriin.", + "message": "Siirsi kohteen \"$ID$\" roskakoriin.", "placeholders": { "id": { "content": "$1", @@ -2874,7 +2874,7 @@ } }, "movedItemIdToOrg": { - "message": "Kohde $ID$ siirrettiin organisaatiolle.", + "message": "Siirsi kohteen \"$ID$\" organisaatiolle.", "placeholders": { "id": { "content": "$1", @@ -2886,7 +2886,7 @@ "message": "Näytä kaikki kirjautumisvaihtoehdot" }, "viewedItemId": { - "message": "Kohdetta $ID$ tarkasteltu.", + "message": "Tarkasteli kohetta \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -2895,7 +2895,7 @@ } }, "viewedPasswordItemId": { - "message": "Tarkasteltiin kohteen $ID$ salasanaa.", + "message": "Näytti kohteen \"$ID$\" salasanan.", "placeholders": { "id": { "content": "$1", @@ -2904,7 +2904,7 @@ } }, "viewedHiddenFieldItemId": { - "message": "Tarkasteltiin kohteen $ID$ piilotettua kenttää.", + "message": "Näytti kohteen \"$ID$\" piilotetun kentän.", "placeholders": { "id": { "content": "$1", @@ -2913,7 +2913,7 @@ } }, "viewedCardNumberItemId": { - "message": "Tarkasteltiin kohteen $ID$ korttinumeroa.", + "message": "Näytti kortin \"$ID$\" numeron.", "placeholders": { "id": { "content": "$1", @@ -2922,7 +2922,7 @@ } }, "viewedSecurityCodeItemId": { - "message": "Tarkasteltiin kohteen $ID$ turvakoodia.", + "message": "Näytti kortin \"$ID$\" turvakoodin.", "placeholders": { "id": { "content": "$1", @@ -2949,7 +2949,7 @@ } }, "copiedPasswordItemId": { - "message": "Kopioitiin kohteen $ID$ salasana.", + "message": "Kopioi kohteen \"$ID$\" salasanan.", "placeholders": { "id": { "content": "$1", @@ -2958,7 +2958,7 @@ } }, "copiedHiddenFieldItemId": { - "message": "Kopioitiin kohteen $ID$ piilotettu kenttä.", + "message": "Kopioi kohteen \"$ID$\" piilotetun kentän.", "placeholders": { "id": { "content": "$1", @@ -2967,7 +2967,7 @@ } }, "copiedSecurityCodeItemId": { - "message": "Kohteen $ID$ turvakoodi kopioitu.", + "message": "Kopioi kortin \"$ID$\" turvakoodin.", "placeholders": { "id": { "content": "$1", @@ -2976,7 +2976,7 @@ } }, "autofilledItemId": { - "message": "Täytti kohteen $ID$ automaattisesti.", + "message": "Automaattitäytti kohteen \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -2985,7 +2985,7 @@ } }, "createdCollectionId": { - "message": "Kokoelma $ID$ luotu.", + "message": "Loi kokoelman \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -2994,7 +2994,7 @@ } }, "editedCollectionId": { - "message": "Muokattiin kokoelmaa $ID$.", + "message": "Muokkasi kokoelmaa \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3006,7 +3006,7 @@ "message": "Kokoelmat poistettiin" }, "deletedCollectionId": { - "message": "Poistettiin kokoelma $ID$.", + "message": "Poisti kokoelman \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3015,7 +3015,7 @@ } }, "editedPolicyId": { - "message": "Muokattiin käytäntöä $ID$.", + "message": "Muokkasi käytäntöä \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3024,7 +3024,7 @@ } }, "createdGroupId": { - "message": "Ryhmä $ID$ luotu.", + "message": "Loi ryhmän \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3033,7 +3033,7 @@ } }, "editedGroupId": { - "message": "Muokattiin ryhmää $ID$.", + "message": "Muokkasi ryhmää \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3042,7 +3042,7 @@ } }, "deletedGroupId": { - "message": "Poistettiin ryhmä $ID$.", + "message": "Poisti ryhmän \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3060,7 +3060,7 @@ } }, "removedUserId": { - "message": "Poistettiin käyttäjä $ID$.", + "message": "Poisti käyttäjän \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3069,7 +3069,7 @@ } }, "removeUserIdAccess": { - "message": "Poista jäsenen $ID$ käyttöoikeudet", + "message": "Poista käyttäjän $ID$ käyttöoikeus", "placeholders": { "id": { "content": "$1", @@ -3078,7 +3078,7 @@ } }, "revokedUserId": { - "message": "Mitätöitiin organisaation käyttöoikeudet käyttäjältä $ID$.", + "message": "Mitätöi käyttäjän \"$ID$\" käyttöoikeuden organisaatioon.", "placeholders": { "id": { "content": "$1", @@ -3087,7 +3087,7 @@ } }, "restoredUserId": { - "message": "Palautettiin organisaation käyttöoikeudet käyttäjälle $ID$.", + "message": "Palautti käyttäjän \"$ID$\" käyttöoikeuden organisaatioon.", "placeholders": { "id": { "content": "$1", @@ -3096,7 +3096,7 @@ } }, "revokeUserId": { - "message": "Mitätöi käyttöoikeudet käyttäjältä $ID$", + "message": "Mitätöi käyttäjän $ID$ käyttöoikeus", "placeholders": { "id": { "content": "$1", @@ -3105,7 +3105,7 @@ } }, "createdAttachmentForItem": { - "message": "Tiedostoliite luotu kohteelle $ID$.", + "message": "Lisäsi tiedostoliitteen kohteeseen \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3114,7 +3114,7 @@ } }, "deletedAttachmentForItem": { - "message": "Poistettiin kohteen $ID$ tiedostoliite.", + "message": "Poisti tiedostoliitteen kohteesta \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3123,7 +3123,7 @@ } }, "editedCollectionsForItem": { - "message": "Muokattiin kohteen $ID$ kokoelmia.", + "message": "Muokkasi kohteen \"$ID$\" kokoelmia.", "placeholders": { "id": { "content": "$1", @@ -3132,7 +3132,7 @@ } }, "invitedUserId": { - "message": "Kutsuttiin käyttäjä $ID$.", + "message": "Kutsui käyttäjän \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3141,7 +3141,7 @@ } }, "confirmedUserId": { - "message": "Vahvistettiin käyttäjä $ID$.", + "message": "Vahvisti käyttäjän \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3150,7 +3150,7 @@ } }, "editedUserId": { - "message": "Muokattiin käyttäjää $ID$.", + "message": "Muokkasi käyttäjää \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3159,7 +3159,7 @@ } }, "editedGroupsForUser": { - "message": "Muokattiin käyttäjän $ID$ ryhmiä.", + "message": "Muokkasi käyttäjän \"$ID$\" ryhmiä.", "placeholders": { "id": { "content": "$1", @@ -3168,7 +3168,7 @@ } }, "unlinkedSsoUser": { - "message": "Kertakirjautumisen liitos poistettiin käyttäjältä $ID$.", + "message": "Irrotti käyttäjän \"$ID$\" kertakirjautumisesta.", "placeholders": { "id": { "content": "$1", @@ -3177,7 +3177,7 @@ } }, "createdOrganizationId": { - "message": "Organisaatio $ID$ luotu.", + "message": "Loi organisaation \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3186,7 +3186,7 @@ } }, "addedOrganizationId": { - "message": "Organisaatio $ID$ luotu.", + "message": "Lisäsi organisaation \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3195,7 +3195,7 @@ } }, "removedOrganizationId": { - "message": "Poistettiin organisaatio $ID$.", + "message": "Poisti organisaation \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -3204,7 +3204,7 @@ } }, "accessedClientVault": { - "message": "Organisaation $ID$ holvia käytetty.", + "message": "Avasi organisaation \"$ID$\" holvin.", "placeholders": { "id": { "content": "$1", @@ -3405,7 +3405,7 @@ "message": "Verotiedot" }, "taxInformationDesc": { - "message": "Yhdysvalloissa olevilta asiakkailta vaaditaan postinumero myyntiverotuksen vaatimusten vuoksi. Muiden maiden asiakkaat voivat halutessaan toimittaa verotunnistenumeron (ALV/GST) ja/tai osoitteen, joka kirjataan laskuihin." + "message": "Yhdysvalloissa olevilta asiakkailta vaaditaan postinumero myyntiverotuksen vaatimusten vuoksi. Muiden maiden asiakkaat voivat halutessaan ilmoittaa verotunnistenumeron (ALV/GST) ja/tai osoitteen, joka kirjataan laskuihin." }, "billingPlan": { "message": "Tilaustyyppi", @@ -3486,17 +3486,17 @@ "message": "Syötä asennuksesi ID-tunnus" }, "limitSubscriptionDesc": { - "message": "Aseta tilaukseesi sisältyvä jäsenpaikkojen määrä. Määrän täytyttyä et voi kutsua uusia jäseniä." + "message": "Rajoita tilauksesi jäsenpaikkojen enimmäismäärää. Määrän täytyttyä et voi kutsua uusia jäseniä." }, "limitSmSubscriptionDesc": { - "message": "Aseta Salaisuushallinta-tilaukseesi sisältyvä jäsenpaikkojen määrä. Määrän täytyttyä et voi kutsua uusia jäseniä." + "message": "Rajoita Salaisuushallinta-tilauksesi jäsenpaikkojen enimmäismäärää. Määrän täytyttyä et voi kutsua uusia jäseniä." }, "maxSeatLimit": { "message": "Käyttäjäpaikkojen enimmäismäärä (valinnainen)", "description": "Upper limit of seats to allow through autoscaling" }, "maxSeatCost": { - "message": "Käyttäjäpaikkojen hintaennuste" + "message": "Käyttäjäpaikkojen mahdollinen enimmäishinta" }, "addSeats": { "message": "Lisää käyttäjäpaikkoja", @@ -3537,10 +3537,10 @@ "message": "Mikäli tarvitset apua tilauksesi hallinnassa, ole yhteydessä asiakaspalveluun." }, "subscriptionUserSeatsUnlimitedAutoscale": { - "message": "Tilausmuutokset aiheuttavat suhteutettuja laskutusmuutoksia. Jos hiljattain kutsuttujen jäsenien määrä ylittää tilauksesi jäsenpaikkojen enimmäismäärän, veloitetaan suhteutettu hinta uusista jäsenistä välittömästi." + "message": "Tilausmuutokset aiheuttavat suhteutettuja laskutusmuutoksia. Jos hiljattain kutsuttujen jäsenten määrä ylittää tilauksesi jäsenpaikkojen määrän, veloitetaan suhteutettu hinta uusista jäsenistä välittömästi." }, "subscriptionUserSeatsLimitedAutoscale": { - "message": "Tilausmuutokset aiheuttavat suhteutettuja laskutusmuutoksia. Jos hiljattain kutsuttujen jäsenien määrä ylittää tilauksesi jäsenpaikkojen enimmäismäärän, veloitetaan suhteutettu hinta uusista jäsenistä välittömästi, kunnes $MAX$ paikan enimmäismäärä täyttyy.", + "message": "Tilausmuutokset aiheuttavat suhteutettuja laskutusmuutoksia. Jos hiljattain kutsuttujen jäsenten määrä ylittää tilauksesi jäsenpaikkojen määrän, veloitetaan suhteutettu hinta uusista jäsenistä välittömästi, kunnes $MAX$ paikan enimmäismäärä täyttyy.", "placeholders": { "max": { "content": "$1", @@ -4044,7 +4044,7 @@ "message": "Voit nyt sulkea tämän välilehden ja jatkaa laajennuksessa." }, "youSuccessfullyLoggedIn": { - "message": "Kirjauduit sisään" + "message": "Kirjautuminen onnistui" }, "thisWindowWillCloseIn5Seconds": { "message": "Tämä ikkuna sulkeutuu automaattisesti 5 sekunnin kuluttua" @@ -4266,7 +4266,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "noSendsInList": { - "message": "Ei näytettäviä Sendejä.", + "message": "Näytettäviä Sendejä ei ole.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "emergencyAccess": { @@ -4464,7 +4464,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "modifiedPolicyId": { - "message": "Käytäntöä $ID$ muokattu.", + "message": "Muokkasi käytäntöä \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -4704,7 +4704,7 @@ "message": "Eroaminen onnistui!" }, "eventEnrollAccountRecovery": { - "message": "Käyttäjä $ID$ liittyi tilin palautusapuun.", + "message": "Käyttäjä \"$ID$\" liittyi tilin palautusapuun.", "placeholders": { "id": { "content": "$1", @@ -4713,7 +4713,7 @@ } }, "eventWithdrawAccountRecovery": { - "message": "Käyttäjä $ID$ erosi tilin palautusavusta.", + "message": "Käyttäjä \"$ID$\" erosi tilin palautusavusta.", "placeholders": { "id": { "content": "$1", @@ -4722,7 +4722,7 @@ } }, "eventAdminPasswordReset": { - "message": "Käyttäjän $ID$ pääsalasanan palautus.", + "message": "Käyttäjän \"$ID$\" pääsalasana nollattiin.", "placeholders": { "id": { "content": "$1", @@ -4731,7 +4731,7 @@ } }, "eventResetSsoLink": { - "message": "Poista käyttäjän $ID$ kertakirjaumisliitos", + "message": "Käyttäjän $ID$ kertakirjaumisliitos nollattiin.", "placeholders": { "id": { "content": "$1", @@ -4740,7 +4740,7 @@ } }, "firstSsoLogin": { - "message": "$ID$ kirjautui ensimmäisen kerran kertakirjautumisen välityksellä", + "message": "Käyttäjä \"$ID$\" kirjautui ensimmäisen kerran kertakirjautumisen välityksellä.", "placeholders": { "id": { "content": "$1", @@ -4908,7 +4908,7 @@ "message": "Asiakkaat" }, "client": { - "message": "Asiakas", + "message": "Pääte", "description": "This is used as a table header to describe which client application created an event log." }, "providerAdmin": { @@ -5204,7 +5204,7 @@ "message": "Vahvista varmenteet" }, "spUniqueEntityId": { - "message": "Aseta yksilöllinen SP entity ID" + "message": "Aseta yksilöllinen \"SP entity ID\"" }, "spUniqueEntityIdDesc": { "message": "Luo yksilöllinen tunniste organisaatiollesi." @@ -5592,7 +5592,7 @@ } }, "characterMaximum": { - "message": "Enintään $MAX$ merkkiä", + "message": "Enintään $MAX$ merkkiä.", "placeholders": { "max": { "content": "$1", @@ -5934,13 +5934,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avaa DUO ja viimeistele kirjautuminen seuraamalla ohjeita." + "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." }, "duoRequiredByOrgForAccount": { - "message": "Tilisi vaatii kaksivaiheisen DUO-kirjautumisen." + "message": "Tilillesi kirjautuminen vaatii Duo-vahvistuksen." }, "launchDuo": { - "message": "Avaa DUO" + "message": "Avaa Duo" }, "turnOn": { "message": "Ota käyttöön" @@ -6138,7 +6138,7 @@ "description": "Title for creating a new service account." }, "secretsNoItemsTitle": { - "message": "Näytettäviä salaisuuksia ei ole", + "message": "Näytettäviä salaisuuksia ei ole.", "description": "Empty state to indicate that there are no secrets to display." }, "secretsNoItemsMessage": { @@ -6329,7 +6329,7 @@ "description": "This message is displayed in a dialog box as a warning before proceeding with project deletion." }, "projectsNoItemsTitle": { - "message": "Näytettäviä projekteja ei ole", + "message": "Näytettäviä projekteja ei ole.", "description": "Empty state to be displayed when there are no projects to display in the list." }, "projectsNoItemsMessage": { @@ -6368,7 +6368,7 @@ "description": "Label for the access level of an access token (Read only)." }, "accessTokensNoItemsTitle": { - "message": "Näytettäviä käyttötunnisteita ei ole", + "message": "Näytettäviä käyttötunnisteita ei ole.", "description": "Title to be displayed when there are no access tokens to display in the list." }, "accessTokensNoItemsDesc": { @@ -6497,7 +6497,7 @@ "message": "Jäseniä ei ole lisätty" }, "noGroupsAdded": { - "message": "Ryhmiä ei ole lisätty" + "message": "Ryhmiä ei ole lisätty." }, "group": { "message": "Ryhmä" @@ -6623,7 +6623,7 @@ } }, "domainVerifiedEvent": { - "message": "Verkkotunnus $DOMAIN$ vahvistettiin", + "message": "Verkkotunnus \"$DOMAIN$\" vahvistettiin.", "placeholders": { "DOMAIN": { "content": "$1", @@ -6632,7 +6632,7 @@ } }, "domainNotVerifiedEvent": { - "message": "Verkkotunnusta $DOMAIN$ ei vahvistettu", + "message": "Verkkotunnusta \"$DOMAIN$\" ei vahvistettu.", "placeholders": { "DOMAIN": { "content": "$1", @@ -6689,7 +6689,7 @@ "message": "Jäsenkohtaisesti määritetyt käyttöoikeudet korvaavat kyseisen jäsenen ryhmän määrittämät oikeudet" }, "noMembersOrGroupsAdded": { - "message": "Jäseniä tai ryhmiä ei ole lisätty" + "message": "Jäseniä tai ryhmiä ei ole lisätty." }, "deleted": { "message": "Poistettiin" @@ -7232,7 +7232,7 @@ "message": "Jäsenien, joiden tileille ei ole asetettu pääsalasanoja, poistaminen voi estää heitä kirjautumasta heidän omille tileilleen." }, "approvedAuthRequest": { - "message": "Käyttäjän $ID$ laite hyväksyttiin.", + "message": "Hyväksyi käyttäjän \"$ID$\" laitteen.", "placeholders": { "id": { "content": "$1", @@ -7241,7 +7241,7 @@ } }, "rejectedAuthRequest": { - "message": "Käyttäjän $ID$ laite hylättiin.", + "message": "Esti käyttäjän \"$ID$\" laitteen.", "placeholders": { "id": { "content": "$1", @@ -7393,7 +7393,7 @@ "message": "Kokoelmien hallinta" }, "collectionManagementDesc": { - "message": "Hallitse organisaation kokoelmien toimintaa." + "message": "Voi hallita organisaation kokoelmien toimintaa." }, "limitCollectionCreationDeletionDesc": { "message": "Rajoita kokoelmien luonti ja poisto omistajille ja ylläpitäjille." @@ -7402,7 +7402,7 @@ "message": "Omistajat ja ylläpitäjät voivat hallita kaikkia kokoelmia ja kohteita." }, "updatedCollectionManagement": { - "message": "Muokkasi kokoelman hallinta-asetusta" + "message": "Kokoelman hallinta-asetusta muutettiin" }, "passwordManagerPlanPrice": { "message": "Salasanahallinnan tilauksen hinta" @@ -7465,7 +7465,7 @@ "message": "Suojausavain ei kopioidu kloonattuun kohteeseen. Haluatko jatkaa kloonausta?" }, "modifiedCollectionManagement": { - "message": "Muokkasi kokoelman hallinta-asetusta $ID$.", + "message": "Muokkasi kokoelman hallinta-asetusta \"$ID$\".", "placeholders": { "id": { "content": "$1", @@ -7481,7 +7481,7 @@ "message": "Asenna selainlaajennus" }, "installBrowserExtensionDetails": { - "message": "Laajennuksella voit verkkosovellusta avaamatta tallentaa kirjautumistietoja ja automaattitäyttää lomakkeita." + "message": "Laajennuksella voit tallentaa kirjautumistietoja ja automaattitäyttää lomakkeita avaamatta verkkosovellusta." }, "projectAccessUpdated": { "message": "Projektin käyttöoikeudet on muutettu" @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Liian kallis", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index 46944e87c10..8667028eeb0 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index f5769abce09..2a726cd8b4f 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Trop cher", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Gratuit pour 1 an" } } diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 22ea603b4a0..077d7d9dc65 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 3b5ab5f4590..fd53a201d4d 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index c2ebddb3e30..a340a08fefd 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index f0a7deef806..f45522fda82 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 709c5b8dd0a..4e3f7ec924a 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 716586ef854..d24af81bbef 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index a1e83fb818a..292d81a4e3e 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Troppo costoso", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Gratis per un anno" } } diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index a39c84d08ae..5ef5b955ad8 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "料金が高すぎる", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index f356c267d4b..6391d3f949b 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index 22ea603b4a0..077d7d9dc65 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index 7e6c90ac8b9..d3523dee431 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 099b8975061..1d03d5d3dda 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 90664d12386..ebe2216d7f7 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Pārāk dārgi", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index fca28002279..a5b211d98d8 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index 22ea603b4a0..077d7d9dc65 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index 22ea603b4a0..077d7d9dc65 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index d7b83e6d636..3e89825b273 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index f3e26f430d0..93fa612e28d 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index d9d4159807a..5ae83ef410c 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Te duur", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "1 jaar gratis" } } diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index 562e4248673..6634b02861a 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index 22ea603b4a0..077d7d9dc65 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 9be37788b27..c3d9408510c 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Zbyt drogo", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Za darmo na 1 rok" } } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 2331b4ea637..d88cea26dc4 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -1069,7 +1069,7 @@ "message": "Exportar" }, "exportFrom": { - "message": "Export from" + "message": "Exportar de" }, "exportVault": { "message": "Exportar Cofre" @@ -1148,7 +1148,7 @@ "message": "Comprimento" }, "passwordMinLength": { - "message": "Minimum password length" + "message": "Tamanho mínimo da senha" }, "uppercase": { "message": "Maiúsculas (A-Z)", @@ -2541,7 +2541,7 @@ } }, "trialSecretsManagerThankYou": { - "message": "Thanks for signing up for Bitwarden Secrets Manager for $PLAN$!", + "message": "Obrigado por se inscrever no Bitwarden Secrets Manager para $PLAN$!", "placeholders": { "plan": { "content": "$1", @@ -7067,24 +7067,24 @@ "message": "bitwarden.eu" }, "smProjectDeleteAccessRestricted": { - "message": "You don't have permissions to delete this project", + "message": "Você não tem permissão para excluir este projeto", "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": "Os projetos a seguir não podem ser excluídos. Deseja continuar?", "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": "Atualizar as definições do KDF" }, "loginInitiated": { - "message": "Login initiated" + "message": "Sessão iniciada" }, "deviceApprovalRequired": { "message": "Device approval required. Select an approval option below:" }, "rememberThisDevice": { - "message": "Remember this device" + "message": "Lembrar deste dispositivo" }, "uncheckIfPublicDevice": { "message": "Uncheck if using a public device" @@ -7093,16 +7093,16 @@ "message": "Approve from your other device" }, "requestAdminApproval": { - "message": "Request admin approval" + "message": "Solicitar aprovação do administrador" }, "approveWithMasterPassword": { - "message": "Approve with master password" + "message": "Aprovar com a senha mestre" }, "trustedDeviceEncryption": { "message": "Trusted device encryption" }, "trustedDevices": { - "message": "Trusted devices" + "message": "Dispositivos confiáveis" }, "memberDecryptionOptionTdeDescriptionPartOne": { "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", @@ -7113,7 +7113,7 @@ "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 single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionPartTwo": { - "message": "policy,", + "message": "política,", "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 single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionLinkTwo": { @@ -7121,7 +7121,7 @@ "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 single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionPartThree": { - "message": "policy, and", + "message": "política e", "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 single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionLinkThree": { @@ -7154,7 +7154,7 @@ "description": "Default title for the user verification dialog." }, "recoverAccount": { - "message": "Recover account" + "message": "Recuperar conta" }, "updatedTempPassword": { "message": "User updated a password issued through account recovery." @@ -7295,13 +7295,13 @@ "message": "Trouble logging in?" }, "loginApproved": { - "message": "Login approved" + "message": "Sessão aprovada" }, "userEmailMissing": { - "message": "User email missing" + "message": "E-mail do usuário ausente" }, "deviceTrusted": { - "message": "Device trusted" + "message": "Dispositivo confiável" }, "sendsNoItemsTitle": { "message": "Não há Envios ativos", @@ -7315,7 +7315,7 @@ "message": "Convidar usuários" }, "secretsManagerForPlan": { - "message": "Secrets Manager for $PLAN$", + "message": "Gerenciador de segredos para $PLAN$", "placeholders": { "plan": { "content": "$1", @@ -7330,13 +7330,13 @@ "message": "Free 2-person Organizations" }, "unlimitedSecrets": { - "message": "Unlimited secrets" + "message": "Segredos ilimitados" }, "unlimitedProjects": { - "message": "Unlimited projects" + "message": "Projetos ilimitados" }, "projectsIncluded": { - "message": "$COUNT$ projects included", + "message": "$COUNT$ projetos incluídos", "placeholders": { "count": { "content": "$1", @@ -7345,7 +7345,7 @@ } }, "serviceAccountsIncluded": { - "message": "$COUNT$ service accounts included", + "message": "$COUNT$ contas de serviço incluídas", "placeholders": { "count": { "content": "$1", @@ -7354,7 +7354,7 @@ } }, "additionalServiceAccountCost": { - "message": "$COST$ per month for additional service accounts", + "message": "$COST$ por mês para contas de serviço adicionais", "placeholders": { "cost": { "content": "$1", @@ -7369,7 +7369,7 @@ "message": "Add Secrets Manager to your upgraded plan to maintain access to any secrets created with your previous plan." }, "additionalServiceAccounts": { - "message": "Additional service accounts" + "message": "Contas de serviço adicionais" }, "includedServiceAccounts": { "message": "O seu plano vem com $COUNT$ contas de serviço.", @@ -7405,31 +7405,31 @@ "message": "Configuração da gestão de coleção atualizada" }, "passwordManagerPlanPrice": { - "message": "Password Manager plan price" + "message": "Preço do plano do Gerenciador de Senha" }, "secretsManagerPlanPrice": { - "message": "Secrets Manager plan price" + "message": "Preço do plano do Gerenciador de Segredos" }, "passwordManager": { - "message": "Password Manager" + "message": "Gerenciador de senha" }, "freeOrganization": { - "message": "Free Organization" + "message": "Organização gratuita" }, "limitServiceAccounts": { - "message": "Limit service accounts (optional)" + "message": "Limitar contas de serviço (opcional)" }, "limitServiceAccountsDesc": { "message": "Set a limit for your service accounts. Once this limit is reached, you will not be able to create new service accounts." }, "serviceAccountLimit": { - "message": "Service account limit (optional)" + "message": "Limite de contas de serviço (opcional)" }, "maxServiceAccountCost": { "message": "Max potential service account cost" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Conectado!" }, "beta": { "message": "Beta" @@ -7456,7 +7456,7 @@ "message": "Pelo menos um membro ou grupo deve ter poder gerenciar a permissão." }, "typePasskey": { - "message": "Passkey" + "message": "Chave de acesso" }, "passkeyNotCopied": { "message": "Passkey will not be copied" @@ -7539,7 +7539,7 @@ "message": "Organization information" }, "confirmationDetails": { - "message": "Confirmation details" + "message": "Detalhes da confirmação" }, "smFreeTrialThankYou": { "message": "Thank you for signing up for Bitwarden Secrets Manager!" @@ -7548,7 +7548,7 @@ "message": "We've sent a confirmation email to your email at " }, "confirmCollectionEnhancementsDialogTitle": { - "message": "This action is irreversible" + "message": "Esta ação é irreversível" }, "confirmCollectionEnhancementsDialogContent": { "message": "Turning on this feature will deprecate the manager role and replace it with a Can manage permission. This will take a few moments. Do not make any organization changes until it is complete. Are you sure you want to proceed?" @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index d94801a8890..e4f1a26a245 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Demasiado caro", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Gratuito durante 1 ano" } } diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index 19d5d176045..40133244151 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index dec47c2dc6d..d4028a1798d 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -4044,10 +4044,10 @@ "message": "Теперь вы можете закрыть эту вкладку и продолжить в расширении." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Вы успешно авторизовались" }, "thisWindowWillCloseIn5Seconds": { - "message": "This window will automatically close in 5 seconds" + "message": "Это окно автоматически закроется через 5 секунд" }, "includeAllTeamsFeatures": { "message": "Все возможности Teams, плюс:" @@ -5934,13 +5934,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустите DUO и следуйте шагам для завершения авторизации." + "message": "Запустите Duo и следуйте шагам для завершения авторизации." }, "duoRequiredByOrgForAccount": { - "message": "Для вашего аккаунта требуется двухэтапная аутентификация DUO." + "message": "Для вашего аккаунта требуется двухэтапная аутентификация Duo." }, "launchDuo": { - "message": "Запустить DUO" + "message": "Запустить Duo" }, "turnOn": { "message": "Включить" @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Слишком дорого", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index 94187f28b0a..cabe12633c6 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index a0e5537feb3..322b9832df4 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index 6b680e8a454..f2438fba975 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 923523c7081..611b13b7d97 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Превише скупо", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index b60d3ea7128..ab592414137 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index 3c45934b311..6bc7536a227 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "För dyrt", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Gratis i 1 år" } } diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index 22ea603b4a0..077d7d9dc65 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index 18b4ede3986..b0a1f6b302e 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index 2371a62ead8..0de80ffee9f 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Çok pahalı", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 1633f3a3adf..0ae07c9ba56 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Висока ціна", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index e5372785341..a253322ff97 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index b72592d629b..bea60104478 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -1348,15 +1348,15 @@ "message": "导入数据" }, "onboardingImportDataDetailsPartOne": { - "message": "If you don't have any data to import, you can create a ", + "message": "如果您没有任何数据要导入,您可以创建一个 ", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "onboardingImportDataDetailsLink": { - "message": "new item", + "message": "新项目", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "onboardingImportDataDetailsPartTwo": { - "message": " instead. You may need to wait until your administrator confirms your organization membership.", + "message": " 。您可能需要等待您的管理员确认您的组织成员资格。", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "importError": { @@ -4047,7 +4047,7 @@ "message": "您已成功登录" }, "thisWindowWillCloseIn5Seconds": { - "message": "此窗口将在5秒后自动关闭" + "message": "此窗口将在 5 秒后自动关闭" }, "includeAllTeamsFeatures": { "message": "所有团队版功能,以及:" @@ -6931,7 +6931,7 @@ "description": "Software Development Kit" }, "createAnAccount": { - "message": "Create an account" + "message": "创建账户" }, "createSecret": { "message": "创建一个机密" @@ -7478,10 +7478,10 @@ "description": "This is followed a by a hyperlink to the help website." }, "installBrowserExtension": { - "message": "Install browser extension" + "message": "安装浏览器扩展" }, "installBrowserExtensionDetails": { - "message": "Use the extension to quickly save logins and auto-fill forms without opening the web app." + "message": "使用扩展快速保存登录信息和自动填充表单,无需打开网页应用程序。" }, "projectAccessUpdated": { "message": "工程访问权限已更新" @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "太贵了", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index de2c4da2280..33e7ca53a51 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -7584,5 +7584,8 @@ "tooExpensive": { "message": "Too expensive", "description": "An option for the offboarding survey shown when a user cancels their subscription." + }, + "freeForOneYear": { + "message": "Free for 1 year" } } From f6203f8f5a973b6fe2db76117328a45fff011a03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 12:06:19 +0000 Subject: [PATCH 003/124] Autosync the updated translations (#8059) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 14 +-- apps/browser/src/_locales/az/messages.json | 56 +++++------ apps/browser/src/_locales/be/messages.json | 14 +-- apps/browser/src/_locales/bg/messages.json | 20 ++-- apps/browser/src/_locales/bn/messages.json | 14 +-- apps/browser/src/_locales/bs/messages.json | 14 +-- apps/browser/src/_locales/ca/messages.json | 16 ++-- apps/browser/src/_locales/cs/messages.json | 16 ++-- apps/browser/src/_locales/cy/messages.json | 16 ++-- apps/browser/src/_locales/da/messages.json | 22 ++--- apps/browser/src/_locales/de/messages.json | 20 ++-- apps/browser/src/_locales/el/messages.json | 14 +-- apps/browser/src/_locales/en_GB/messages.json | 24 ++--- apps/browser/src/_locales/en_IN/messages.json | 14 +-- apps/browser/src/_locales/es/messages.json | 14 +-- apps/browser/src/_locales/et/messages.json | 14 +-- apps/browser/src/_locales/eu/messages.json | 14 +-- apps/browser/src/_locales/fa/messages.json | 14 +-- apps/browser/src/_locales/fi/messages.json | 28 +++--- apps/browser/src/_locales/fil/messages.json | 14 +-- apps/browser/src/_locales/fr/messages.json | 94 +++++++++---------- apps/browser/src/_locales/gl/messages.json | 14 +-- apps/browser/src/_locales/he/messages.json | 14 +-- apps/browser/src/_locales/hi/messages.json | 14 +-- apps/browser/src/_locales/hr/messages.json | 14 +-- apps/browser/src/_locales/hu/messages.json | 20 ++-- apps/browser/src/_locales/id/messages.json | 14 +-- apps/browser/src/_locales/it/messages.json | 16 ++-- apps/browser/src/_locales/ja/messages.json | 20 ++-- apps/browser/src/_locales/ka/messages.json | 14 +-- apps/browser/src/_locales/km/messages.json | 14 +-- apps/browser/src/_locales/kn/messages.json | 14 +-- apps/browser/src/_locales/ko/messages.json | 14 +-- apps/browser/src/_locales/lt/messages.json | 66 ++++++------- apps/browser/src/_locales/lv/messages.json | 16 ++-- apps/browser/src/_locales/ml/messages.json | 14 +-- apps/browser/src/_locales/mr/messages.json | 14 +-- apps/browser/src/_locales/my/messages.json | 14 +-- apps/browser/src/_locales/nb/messages.json | 14 +-- apps/browser/src/_locales/ne/messages.json | 14 +-- apps/browser/src/_locales/nl/messages.json | 18 ++-- apps/browser/src/_locales/nn/messages.json | 14 +-- apps/browser/src/_locales/or/messages.json | 14 +-- apps/browser/src/_locales/pl/messages.json | 16 ++-- apps/browser/src/_locales/pt_BR/messages.json | 14 +-- apps/browser/src/_locales/pt_PT/messages.json | 20 ++-- apps/browser/src/_locales/ro/messages.json | 14 +-- apps/browser/src/_locales/ru/messages.json | 24 ++--- apps/browser/src/_locales/si/messages.json | 14 +-- apps/browser/src/_locales/sk/messages.json | 16 ++-- apps/browser/src/_locales/sl/messages.json | 14 +-- apps/browser/src/_locales/sr/messages.json | 20 ++-- apps/browser/src/_locales/sv/messages.json | 44 ++++----- apps/browser/src/_locales/te/messages.json | 14 +-- apps/browser/src/_locales/th/messages.json | 14 +-- apps/browser/src/_locales/tr/messages.json | 16 ++-- apps/browser/src/_locales/uk/messages.json | 16 ++-- apps/browser/src/_locales/vi/messages.json | 14 +-- apps/browser/src/_locales/zh_CN/messages.json | 20 ++-- apps/browser/src/_locales/zh_TW/messages.json | 14 +-- 60 files changed, 575 insertions(+), 575 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index f427cc3de65..31e91d7741c 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index b11fc958961..7860c408242 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -494,10 +494,10 @@ "message": "Yeni hesabınız yaradıldı! İndi giriş edə bilərsiniz." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Uğurla giriş etdiniz" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Bu pəncərəni bağlaya bilərsiniz" }, "masterPassSent": { "message": "Sizə ana parol ipucunuz olan bir e-poçt göndərdik." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Qovluq seçin..." }, + "noFoldersFound": { + "message": "Heç bir qovluq tapılmadı", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Təşkilatınızın icazələri güncəlləndi və bir ana parol ayarlamağınızı tələb edir.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2013,7 +2017,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { - "message": "Verification required", + "message": "Doğrulama tələb olunur", "description": "Default title for the user verification dialog." }, "hours": { @@ -2654,40 +2658,40 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Yenidən sına" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Bu əməliyyat üçün doğrulama tələb olunur. Davam etmək üçün bir PIN təyin edin." }, "setPin": { - "message": "Set PIN" + "message": "PIN təyin et" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Biometriklə doğrula" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Təsdiq gözlənilir" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Biometrik tamamlana bilmədi." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Fərqli bir üsul lazımdır?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Ana parolu istifadə et" }, "usePin": { - "message": "Use PIN" + "message": "PIN-i istifadə et" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Biometrik istifadə et" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "E-poçtunuza göndərilmiş doğrulama kodunu daxil edin." }, "resendCode": { - "message": "Resend code" + "message": "Kodu təkrar göndər" }, "total": { "message": "Cəmi" @@ -2702,19 +2706,19 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Duo-nu başladın və giriş prosesini tamamlamaq üçün addımları izləyin." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { - "message": "Popout extension" + "message": "Popout uzantısı" }, "launchDuo": { - "message": "Launch Duo" + "message": "Duo-nu başlat" }, "importFormatError": { "message": "Data doğru format edilməyib. Lütfən daxilə köçürmə faylınızı yoxlayıb yenidən sınayın." @@ -2848,13 +2852,13 @@ "message": "Yanlış istifadəçi adı və ya parol" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Yanlış parol" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Yanlış kod" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "Yanlış PIN" }, "multifactorAuthenticationFailed": { "message": "Çox faktorlu kimlik doğrulama uğursuz oldu" @@ -2974,10 +2978,6 @@ "message": "Bu seçimin yox sayılması, \"Bitwarden\"in və brauzerinizin avto-doldurma menyuları arasında ziddiyyətlərə səbəb ola bilər.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Bu əməliyyat, Bitwarden uzantısını yenidən başladacaq. Bu seçimin yox sayılması, \"Bitwarden\"in və brauzerinizin avto-doldurma menyuları arasında ziddiyyətlərə səbəb ola bilər.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "\"Bitwarden\"i ilkin parol meneceriniz olaraq təyin edin", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 3eedeb15bf9..4e70cfedd70 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Выбраць папку..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 02f1a6c983d..e0069a34d37 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -494,10 +494,10 @@ "message": "Абонаментът ви бе създаден. Вече можете да се впишете." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Вписахте се успешно" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Може да затворите този прозорец" }, "masterPassSent": { "message": "Изпратихме ви писмо с подсказка за главната ви парола." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Избиране на папка..." }, + "noFoldersFound": { + "message": "Няма намерени папки", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Правата Ви в организацията бяха променени, необходимо е да зададете главна парола.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Стартирайте DUO и следвайте инструкциите, за да завършите вписването." }, - "duoRequiredByOrgForAccount": { - "message": "Вашата регистрация изисква двустепенно удостоверяване чрез DUO." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Отворете разширението в нов прозорец, за да завършите вписването" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Отваряне на разширението в нов прозорец" @@ -2974,10 +2978,6 @@ "message": "Ако пренебрегнете тази настройка, може да има конфликт между менюто за автоматично попълване на Битуорден и това на браузъра.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Това действие ще рестартира добавката на Битуорден. Ако пренебрегнете тази настройка, може да има конфликт между менюто за автоматично попълване на Битуорден и това на браузъра.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Направете Битуорден своя управител на пароли по подразбиране", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 2c128990ace..3bbb51a4085 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index e12df296e96..a5d158ad613 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 767c27e76d9..0917db0c11a 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Seleccioneu la carpeta..." }, + "noFoldersFound": { + "message": "No s'ha trobat cap carpeta", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Els permisos de la vostra organització s'han actualitzat, cal que establiu una contrasenya mestra.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Inicieu DUO i seguiu els passos per finalitzar la sessió." }, - "duoRequiredByOrgForAccount": { - "message": "Es requereix l'inici de sessió en dos passos de DUO al vostre compte." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Obriu l'extensió en una finestra nova per completar l'inici de sessió" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Extensió emergent" @@ -2974,10 +2978,6 @@ "message": "Si ignoreu aquesta opció pot provocar conflictes entre el menú d'emplenament automàtic de Bitwarden i el del navegador.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Aquesta acció reiniciarà l'extensió Bitwarden. Si ignoreu aquesta opció pot provocar conflictes entre el menú d'emplenament automàtic de Bitwarden i el del vostre navegador.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Feu que Bitwarden siga el vostre gestor de contrasenyes predeterminat", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index 8b8f892867d..e0d1026e6f7 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Vyberte složku..." }, + "noFoldersFound": { + "message": "Nebyly nalezeny žádné složky", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Oprávnění Vaší organizace byla aktualizována. To vyžaduje nastavení hlavního hesla.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Spusťte DUO a pro dokončení přihlášení postupujte podle kroků." }, - "duoRequiredByOrgForAccount": { - "message": "Pro Váš účet je vyžadováno dvoufázové přihlášení DUO." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Pro dokončení přihlášení otevřete rozšíření v novém okně" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Zobrazit okno s doplňkem" @@ -2974,10 +2978,6 @@ "message": "Ignorování této volby může způsobit konflikty mezi nabídkou automatického vyplňování Bitwardenu a Vaším prohlížečem.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Tato akce restartuje rozšíření Bitwardenu. Ignorování této volby může způsobit konflikty mezi nabídkou automatického vyplňování Bitwardenu a prohlížečem.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Nastavit Bitwarden jako výchozí správce hesel", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 71b749aab80..6ab6d9600d2 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -387,7 +387,7 @@ "message": "Gwirio'ch hunaniaeth" }, "yourVaultIsLocked": { - "message": "Mae eich cell dan glo. Gwiriwch eich hunaniaeth i barhau." + "message": "Mae eich cell ar glo. Gwiriwch eich hunaniaeth i barhau." }, "unlock": { "message": "Datgloi" @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Dewis ffolder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index bc50a0da35f..da11b9c2f41 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -494,10 +494,10 @@ "message": "Din nye konto er oprettet! Du kan nu logge ind." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Du er nu logget ind" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Dette vindue kan nu lukkes" }, "masterPassSent": { "message": "Vi har sendt dig en e-mail med dit hovedadgangskodetip." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Vælg mappe..." }, + "noFoldersFound": { + "message": "Ingen mapper fundet", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Organisationstilladelserne er blevet opdateret, og der kræves nu oprettelse af en hovedadgangskode.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,14 +2708,14 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Start DUO og følg trinene for at fuldføre indlogningen." }, - "duoRequiredByOrgForAccount": { - "message": "DUO totrins indlogning kræves for kontoen." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Åbn udvidelsen i et nyt vindue for at fuldføre indlogning" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { - "message": "Popout extension" + "message": "Pop ud-udvidelse" }, "launchDuo": { "message": "Start DUO" @@ -2974,10 +2978,6 @@ "message": "Ignoreres denne indstilling, kan det forårsage konflikter mellem Bitwardens autoudfyld-menu og webbrowsere.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Denne handling vil genstarte Bitwarden-udvidelsen. Ignoreres denne indstilling, kan det forårsage konflikter mellem Bitwardens autoudfyld-menu og webbrowsere.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Lad Bitwarden håndtere adgangskoder som standard", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 3b115a0c24c..1a54c5dc918 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -494,10 +494,10 @@ "message": "Dein neues Konto wurde erstellt! Du kannst dich jetzt anmelden." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Du hast dich erfolgreich angemeldet." }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Du kannst dieses Fenster schließen." }, "masterPassSent": { "message": "Wir haben dir eine E-Mail mit dem Master-Passwort-Hinweis geschickt." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Ordner auswählen..." }, + "noFoldersFound": { + "message": "Keine Ordner gefunden", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Deine Organisationsberechtigungen wurden aktualisiert und verlangen, dass du ein Master-Passwort festlegen musst.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Starte DUO und folge den Schritten, um die Anmeldung zu abzuschließen." }, - "duoRequiredByOrgForAccount": { - "message": "Für dein Konto ist die DUO Zwei-Faktor-Authentifizierung erforderlich." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Öffne die Erweiterung in einem neuen Fenster, um die Anmeldung abzuschließen" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout-Erweiterung" @@ -2974,10 +2978,6 @@ "message": "Das Ignorieren dieser Option kann zu Konflikten zwischen dem Bitwarden Auto-Ausfüllen Menü und dem Browser führen.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Diese Aktion wird die Bitwarden-Erweiterung neu starten. Wenn diese Option ignoriert wird, kann dies zu Konflikten zwischen dem Bitwarden Auto-Ausfüllen Menü und dem Browser führen.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Bitwarden zum Standard-Passwort-Manager machen", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 6ade1f898a6..4520d1b69b4 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Επιλέξτε φάκελο..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 705b2c70838..7cc501d1964 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -1082,7 +1082,7 @@ "message": "If a login form is detected, auto-fill when the web page loads." }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit autofill on page load." + "message": "Compromised or untrusted websites can exploit auto-fill on page load." }, "learnMoreAboutAutofill": { "message": "Learn more about auto-fill" @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organisation permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2304,7 +2308,7 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "Your organization policies have turned on auto-fill on page load." + "message": "Your organisation policies have turned on auto-fill on page load." }, "howToAutofill": { "message": "How to auto-fill" @@ -2702,19 +2706,19 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch DUO and follow the steps to finish logging in." + "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { - "message": "DUO two-step login is required for your account." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" }, "launchDuo": { - "message": "Launch DUO" + "message": "Launch Duo" }, "importFormatError": { "message": "Data is not formatted correctly. Please check your import file and try again." @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index c3e74e7d7f8..f6418a40542 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index ec11968a035..e4c51bd2982 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Seleccione carpeta..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Los permisos de la organización se han actualizado y se requiere el establecimiento de una contraseña maestra.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Pasar por alto esta opción puede causar conflictos entre el menú de relleno automático de Bitwarden y el del navegador.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Esta acción reiniciará la extensión Bitwarden. Pasar por alto esta opción puede causar conflictos entre el menú de relleno automático de Bitwarden y el del navegador.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Hacer de Bitwarden su gestor de contraseñas predeterminado", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 63cf55f1874..274ecb365a3 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Vali kaust..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 0b0c132d3df..5c2611760ee 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Hautatu karpeta..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index b0a44226e65..aa9276d2d47 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "پوشه را انتخاب کنید..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index e0a1e5d27e8..3be1aea1f53 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -494,10 +494,10 @@ "message": "Uusi käyttäjätilisi on luotu! Voit nyt kirjautua sisään." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Kirjautuminen onnistui" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Voit sulkea tämän ikkunan" }, "masterPassSent": { "message": "Lähetimme pääsalasanasi vihjeen sähköpostitse." @@ -1088,7 +1088,7 @@ "message": "Lisätietoja automaattitäytöstä" }, "defaultAutoFillOnPageLoad": { - "message": "Automaattitäytön oletusasetus kirjautumistiedoille" + "message": "Kirjautumistietojen automaattitäytön oletusasetus" }, "defaultAutoFillOnPageLoadDesc": { "message": "Automaattinen täyttö on mahdollista ottaa käyttöön tai poistaa käytöstä kirjautumistietokohtaisesti kirjautumistetoa muokkaamalla." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Valitse kansio..." }, + "noFoldersFound": { + "message": "Ongelmia ei löytynyt", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Organisaatiosi käyttöoikeuksia muutettiin ja tämän seurauksena sinun on asetettava pääsalasana.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2526,7 +2530,7 @@ "description": "Toggling an expand/collapse state." }, "filelessImport": { - "message": "Tuodaanko tiedot Bitwardeniin?", + "message": "Haluatko tuoda tietosi Bitwardeniin?", "description": "Default notification title for triggering a fileless import." }, "lpFilelessImport": { @@ -2702,19 +2706,19 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avaa DUO ja viimeistele kirjautuminen seuraamalla ohjeita." + "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." }, - "duoRequiredByOrgForAccount": { - "message": "Tilisi vaatii kaksivaiheisen DUO-kirjautumisen." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Viimeistele kirjautuminen avaamalla laajennus erilliseen ikkunaan." + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Irrota laajennus" }, "launchDuo": { - "message": "Avaa DUO" + "message": "Avaa Duo" }, "importFormatError": { "message": "Tietoja ei ole muotoiltu oikein. Tarkista tuotava tiedosto ja yritä uudelleen." @@ -2974,10 +2978,6 @@ "message": "Tämän huomiotta jättäminen voi aiheuttaa ongelmia Bitwardenin automaattitäytön valikon ja selaimen välisessä toiminnassa.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Tämä toiminto käynnistää Bitwarden-laajennuksen uudelleen ja sen huomiotta jättäminen voi aiheuttaa ongelmia Bitwardenin automaattitäytön valikon ja selaimen välisessä toiminnassa.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Määritä Bitwarden oletusarvoiseksi salasanahallinnaksi", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index d363b9cebb6..140b0b16fe0 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Pumili ng folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 9a3270cd916..7c6ac3b0ac2 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -107,7 +107,7 @@ "message": "Copier le nom du champ personnalisé" }, "noMatchingLogins": { - "message": "Aucun identifiant correspondant." + "message": "Aucun identifiant correspondant" }, "noCards": { "message": "Aucune carte" @@ -131,7 +131,7 @@ "message": "Connectez-vous à votre coffre" }, "autoFillInfo": { - "message": "Il n'y a pas d'identifiants disponibles à saisir automatiquement pour l'onglet actuel du navigateur." + "message": "Il n'y a pas d'identifiants disponibles pour la saisie automatique dans l'onglet actuel." }, "addLogin": { "message": "Ajouter un identifiant" @@ -140,7 +140,7 @@ "message": "Ajouter un élément" }, "passwordHint": { - "message": "Indice mot de passe" + "message": "Indice de mot de passe" }, "enterEmailToGetHint": { "message": "Saisissez l'adresse électronique de votre compte pour recevoir l'indice de votre mot de passe principal." @@ -177,7 +177,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." }, "yourAccountsFingerprint": { - "message": "La phrase d'empreinte de votre compte", + "message": "Phrase d'empreinte de votre compte", "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": { @@ -229,7 +229,7 @@ "message": "Contacter le support Bitwarden" }, "sync": { - "message": "Synchroniser" + "message": "Synchronisation" }, "syncVaultNow": { "message": "Synchroniser le coffre maintenant" @@ -369,10 +369,10 @@ "message": "Autre" }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Configurez une méthode de déverrouillage pour changer le délai d'attente de votre coffre." + "message": "Configurez une méthode de déverrouillage pour changer le délai d'expiration de votre coffre." }, "unlockMethodNeeded": { - "message": "Configurer une méthode de déverrouillage dans Paramètres" + "message": "Configurer une méthode de déverrouillage dans les Paramètres" }, "rateExtension": { "message": "Noter l'extension" @@ -494,7 +494,7 @@ "message": "Votre nouveau compte a été créé ! Vous pouvez maintenant vous authentifier." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Vous vous êtes connecté avec succès" }, "youMayCloseThisWindow": { "message": "Vous pouvez fermer cette fenêtre" @@ -519,7 +519,7 @@ } }, "autofillError": { - "message": "Impossible de saisir automatiquement l'élément sélectionné sur cette page. Copiez-collez plutôt l'information." + "message": "Impossible de saisir automatiquement l'élément sélectionné sur cette page. Essayez plutôt le copier-coller." }, "totpCaptureError": { "message": "Impossible de scanner le code QR à partir de la page web actuelle" @@ -564,7 +564,7 @@ "message": "Vous pouvez changer votre mot de passe principal depuis le coffre web de bitwarden.com. Voulez-vous visiter le site web maintenant ?" }, "twoStepLoginConfirmation": { - "message": "L'authentification à deux facteurs rend votre compte plus sûr en vous demandant de vérifier votre connexion avec un autre dispositif tel qu'une clé de sécurité, une application d'authentification, un SMS, un appel téléphonique ou un courriel. L'authentification à deux facteurs peut être configurée sur le coffre web de bitwarden.com. Voulez-vous visiter le site web maintenant ?" + "message": "L'authentification à deux facteurs rend votre compte plus sûr en vous demandant de vérifier votre connexion avec un autre dispositif tel qu'une clé de sécurité, une application d'authentification, un SMS, un appel téléphonique ou un courriel. L'authentification à deux facteurs peut être configurée dans le coffre web de bitwarden.com. Voulez-vous visiter le site web maintenant ?" }, "editedFolder": { "message": "Dossier sauvegardé" @@ -650,16 +650,16 @@ "message": "Demander à ajouter un élément si aucun n'est trouvé dans votre coffre." }, "addLoginNotificationDescAlt": { - "message": "Demander d'ajouter un élément s'il n'est pas présent dans le coffre. S'applique à tous les comptes connectés." + "message": "Demandez d'ajouter un élément s'il celui-ci n'est pas trouvé dans votre coffre. S'applique à tous les comptes connectés." }, "showCardsCurrentTab": { - "message": "Afficher les cartes sur la page de l'onglet" + "message": "Afficher les cartes de paiement sur page d'Onglet" }, "showCardsCurrentTabDesc": { "message": "Lister les éléments de la carte sur la page de l'onglet pour faciliter la saisie automatique." }, "showIdentitiesCurrentTab": { - "message": "Afficher les identités sur la page Onglet courant" + "message": "Afficher les identités sur page d'Onglet" }, "showIdentitiesCurrentTabDesc": { "message": "Lister les éléments d'identité sur la page de l'onglet pour faciliter la saisie automatique." @@ -669,7 +669,7 @@ "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "clearClipboardDesc": { - "message": "Effacer automatiquement de votre presse-papiers les valeurs copiées.", + "message": "Efface automatiquement les valeurs copiées de votre presse-papiers.", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "notificationAddDesc": { @@ -679,19 +679,19 @@ "message": "Enregistrer" }, "enableChangedPasswordNotification": { - "message": "Demander à mettre à jour l'identifiant existant" + "message": "Demander à mettre à jour un identifiant existant" }, "changedPasswordNotificationDesc": { "message": "Demander à mettre à jour le mot de passe d'un identifiant lorsqu'un changement est détecté sur un site Web." }, "changedPasswordNotificationDescAlt": { - "message": "Proposer de mettre à jour le mot de passe quand un changement est détecté sur un site web. S'appliquer à tous les comptes connectés." + "message": "Demander à mettre à jour le mot de passe d'un identifiant lorsqu'un changement est détecté sur un site web. S'applique à tous les comptes connectés." }, "enableUsePasskeys": { - "message": "Demander à enregistrer et utiliser les mots de passe" + "message": "Demander à enregistrer et utiliser les clés d'accès" }, "usePasskeysDesc": { - "message": "Proposer d'enregistrer de nouvelles clés d'accès ou bien de se connecter à l'aide de clés déjà stockées dans votre coffre-fort. S'applique à tous les comptes connectés." + "message": "Demander d'enregistrer de nouvelles clés d'accès ou bien de se connecter à l'aide de clés stockées dans votre coffre. S'applique à tous les comptes connectés." }, "notificationChangeDesc": { "message": "Souhaitez-vous mettre à jour ce mot de passe dans Bitwarden ?" @@ -709,10 +709,10 @@ "message": "Afficher les options du menu contextuel" }, "contextMenuItemDesc": { - "message": "Utilisez un clic secondaire pour accéder à la génération de mots de passe et les identifiants correspondants pour le site Web. " + "message": "Utilise un clic secondaire pour accéder à la génération de mots de passe et aux identifiants correspondants pour le site web." }, "contextMenuItemDescAlt": { - "message": "Utilisez un clic secondaire pour accéder à la génération de mot de passe et aux identifiants correspondants au site Web. S'applique à tous les comptes connectés." + "message": "Utilise un clic secondaire pour accéder à la génération de mot de passe et aux identifiants correspondants pour le site web. S'applique à tous les comptes connectés." }, "defaultUriMatchDetection": { "message": "Détection de correspondance URI par défaut", @@ -728,7 +728,7 @@ "message": "Modifier le thème de couleur de l'application." }, "themeDescAlt": { - "message": "Modifier le thème de couleur de l'application. S'applique à tous les comptes connectés." + "message": "Modifie le thème de couleur de l'application. S'applique à tous les comptes connectés." }, "dark": { "message": "Sombre", @@ -907,10 +907,10 @@ "message": "Actualisation terminée" }, "enableAutoTotpCopy": { - "message": "Copier le code TOTP automatiquement" + "message": "Copier TOTP automatiquement" }, "disableAutoTotpCopyDesc": { - "message": "Si un identifiant possède une clé d'authentification, copiez le code de vérification TOTP dans votre presse-papiers lorsque vous saisissez automatiquement l'identifiant." + "message": "Si un identifiant possède une clé d'authentification, copie le code de vérification TOTP dans votre presse-papiers lorsque vous saisissez automatiquement l'identifiant." }, "enableAutoBiometricsPrompt": { "message": "Demander la biométrie au lancement" @@ -1051,11 +1051,11 @@ "message": "Les URLs d'environnement ont été enregistrées." }, "showAutoFillMenuOnFormFields": { - "message": "Afficher le menu de saisie automatique sur les champs du formulaire", + "message": "Afficher le menu de saisie automatique dans les champs d'un formulaire", "description": "Represents the message for allowing the user to enable the auto-fill overlay" }, "showAutoFillMenuOnFormFieldsDescAlt": { - "message": "Appliquer à tous les comptes connectés." + "message": "S'applique à tous les comptes connectés." }, "turnOffBrowserBuiltInPasswordManagerSettings": { "message": "Désactivez les paramètres du gestionnaire de mots de passe intégré à votre navigateur pour éviter les conflits." @@ -1064,11 +1064,11 @@ "message": "Éditer les paramètres du navigateur." }, "autofillOverlayVisibilityOff": { - "message": "Arrêt", + "message": "Désactivé", "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "Quand le champ est sélectionné (a le focus)", + "message": "Lorsque le champ est sélectionné (sur \"focus\")", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { @@ -1079,10 +1079,10 @@ "message": "Saisir automatiquement au chargement de la page" }, "enableAutoFillOnPageLoadDesc": { - "message": "Si un formulaire de connexion est détecté, saisir automatiquement lors du chargement de la page web." + "message": "Si un formulaire de connexion est détecté, il sera saisi automatiquement lors du chargement de la page web." }, "experimentalFeature": { - "message": "Les sites web compromis ou non fiables peuvent exploiter la saisie automatique au chargement de la page." + "message": "les sites web compromis ou non fiables peuvent exploiter la saisie automatique au chargement de la page." }, "learnMoreAboutAutofill": { "message": "En savoir plus sur la saisie automatique" @@ -1165,16 +1165,16 @@ "message": "Afficher les icônes des sites web" }, "faviconDesc": { - "message": "Afficher une image reconnaissable à côté de chaque identifiant." + "message": "Affiche une image reconnaissable à côté de chaque identifiant." }, "faviconDescAlt": { - "message": "Afficher une image reconnaissable à côté de chaque identifiant. S'applique à tous les comptes connectés." + "message": "Affiche une image reconnaissable à côté de chaque identifiant. S'applique à tous les comptes connectés." }, "enableBadgeCounter": { "message": "Afficher le compteur de badge" }, "badgeCounterDesc": { - "message": "Indique le nombre d'identifiants que vous avez pour la page web actuelle." + "message": "Indique le nombre d'identifiants dont vous disposez pour la page web en cours." }, "cardholderName": { "message": "Nom du titulaire de la carte" @@ -1279,7 +1279,7 @@ "message": "Numéro de passeport" }, "licenseNumber": { - "message": "Numéro de permis de Conduire" + "message": "Numéro de licence" }, "email": { "message": "Courriel" @@ -1571,7 +1571,7 @@ "message": "Élément saisi automatiquement" }, "insecurePageWarning": { - "message": "Avertissement : il s'agit d'une page HTTP non sécurisée, et toute information que vous soumettez peut potentiellement être vue et modifiée par d'autres. À l'origine, cet identifiant a été enregistré sur une page sécurisée (HTTPS)." + "message": "Avertissement : il s'agit d'une page HTTP non sécurisée, et toute information que vous soumettez peut potentiellement être vue et modifiée par un tiers. À l'origine, cet identifiant a été enregistré sur une page sécurisée (HTTPS)." }, "insecurePageWarningFillPrompt": { "message": "Voulez-vous toujours saisir automatiquement cet identifiant ?" @@ -1739,10 +1739,10 @@ "message": "Domaines exclus" }, "excludedDomainsDesc": { - "message": "Bitwarden ne proposera pas d'enregistrer les informations de connexion pour ces domaines. Vous devez actualiser la page pour que les modifications prennent effet." + "message": "Bitwarden ne demandera pas d'enregistrer les détails de connexion pour ces domaines. Vous devez actualiser la page pour que les modifications prennent effet." }, "excludedDomainsDescAlt": { - "message": "Bitwarden ne proposera pas d'enregistrer les informations de connexion pour ces domaines pour tous les comptes connectés. Vous devez rafraîchir la page pour appliquer les changements." + "message": "Bitwarden ne demandera pas d'enregistrer les détails de connexion pour ces domaines pour tous les comptes connectés. Vous devez actualiser la page pour que les modifications prennent effet." }, "excludedDomainsInvalidDomain": { "message": "$DOMAIN$ n'est pas un domaine valide", @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Sélectionnez un dossier..." }, + "noFoldersFound": { + "message": "Aucun dossier trouvé", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Les autorisations de votre organisation ont été mises à jour, vous obligeant à définir un mot de passe principal.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2684,7 +2688,7 @@ "message": "Utiliser la biométrie" }, "enterVerificationCodeSentToEmail": { - "message": "Entrez le code de vérification qui a été envoyé à votre adresse courriel." + "message": "Entrez le code de vérification qui a été envoyé à votre adresse de messagerie." }, "resendCode": { "message": "Renvoyer le code" @@ -2704,14 +2708,14 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Lancez DUO et suivez les étapes pour terminer la connexion." }, - "duoRequiredByOrgForAccount": { - "message": "L'authentification à double facteur DUO est requise pour votre compte." + "duoRequiredForAccount": { + "message": "L'authentification à deux facteurs Duo est requise pour votre compte." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Ouvrez l'extension dans une nouvelle fenêtre pour terminer la connexion" + "popoutTheExtensionToCompleteLogin": { + "message": "Faire apparaître l'extension pour terminer la connexion." }, "popoutExtension": { - "message": "Popout extension" + "message": "Détacher l'extension" }, "launchDuo": { "message": "Lancer DUO" @@ -2974,10 +2978,6 @@ "message": "Ignorer cette option peut causer des conflits entre le menu de saisie automatique de Bitwarden et celui de votre navigateur.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Cette action va redémarrer l'extension Bitwarden. Ignorer cette option peut causer des conflits entre le menu de saisie automatique de Bitwarden et celui de votre navigateur.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Faire de Bitwarden votre gestionnaire de mots de passe par défaut", "description": "Label for the setting that allows overriding the default browser autofill settings" @@ -2987,7 +2987,7 @@ "description": "Title for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "privacyPermissionAdditionNotGrantedDescription": { - "message": "Vous devez accorder les autorisations de confidentialité du navigateur à Bitwarden pour le définir comme gestionnaire de mots de passe par défaut.", + "message": "Vous devez accorder les permissions de confidentialité du navigateur à Bitwarden pour le définir comme gestionnaire de mots de passe par défaut.", "description": "Description for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "makeDefault": { diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 63a62db04c4..2682011e8e1 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index 480ee4da2d4..c5ed189b7b6 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "הרשאות הארגון שלך עודכנו, מה שמאלץ אותך להגדיר סיסמה ראשית.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index bbe98ea71fa..af953fe4138 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "फ़ोल्डर चुनें..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index adae8fd1370..da75c55cd78 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Odaberi mapu..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Moraš postaviti glavnu lozinku jer su dopuštenja tvoje organizacije ažurirana.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 1b0d63ebc89..3ce23b177c3 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -494,10 +494,10 @@ "message": "Felhasználódat létrehoztuk. Most már be tudsz jelentkezni." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "A bejelentkezés sikeres volt." }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Most már bezárható ez az ablak." }, "masterPassSent": { "message": "Elküldtünk neked egy mesterjelszó emlékeztetődet tartalmazó E-mailt." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Mappa választása..." }, + "noFoldersFound": { + "message": "Nem találhatók mappák.", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "A szervezeti engedélyek frissítésre kerültek, ezért be kell állítani egy mesterjelszót.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Indítsuk el a DUO-t és kövessük a lépéseket a bejelentkezés befejezéséhez." }, - "duoRequiredByOrgForAccount": { - "message": "A fiókhoz kétlépcsős DUO bejelentkezés szükséges." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "A bejelentkezés befejezéséhez nyissuk meg a bővítményt egy új ablakban." + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Felugró bővítmény" @@ -2974,10 +2978,6 @@ "message": "Ennek az opciónak a figyelmen kívül hagyása ütközést okozhat a Bitwarden automatikus kitöltési menü és a böngésző között.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Ez a művelet újraindítja a Bitwarden bővítményt. Ennek az opciónak a figyelmen kívül hagyása ütközést okozhat a Bitwarden automatikus kitöltési menü és a böngésző között.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Legyen a Bitwarden az alapértelmezett jelszókezelő", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 74c7a87eedb..660d11dc1c9 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Pilih Folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 1b0df65418e..f0cf63c5f3c 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Seleziona cartella..." }, + "noFoldersFound": { + "message": "Nessuna cartella trovata", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Le autorizzazioni della tua organizzazione sono state aggiornate, obbligandoti a impostare una password principale.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Avvia DUO e segui i passaggi per finire di accedere." }, - "duoRequiredByOrgForAccount": { - "message": "Per il tuo account è richiesta la verifica in due passaggi DUO." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Apri l'estensione in una nuova finestra per completare l'accesso" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Estrai estensione" @@ -2974,10 +2978,6 @@ "message": "Se questa opzione è disattivata potrebbe causare conflitti tra il menu di riempimento automatico di Bitwarden e quello del tuo browser.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Questa azione riavvierà l'estensione di Bitwarden. Se questa opzione è disattivata potrebbe causare conflitti tra il menu di riempimento automatico di Bitwarden e quello del tuo browser.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Rendi Bitwarden il tuo password manager predefinito", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index e9d0b5b68d2..43b65a46181 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -494,10 +494,10 @@ "message": "新しいアカウントを作成しました!今すぐログインできます。" }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "ログインに成功しました" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "ウィンドウを閉じて大丈夫です" }, "masterPassSent": { "message": "あなたのマスターパスワードのヒントを記載したメールを送信しました。" @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "フォルダーを選択..." }, + "noFoldersFound": { + "message": "フォルダーが見つかりません", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "組織の権限が更新され、マスターパスワードの設定が必要になりました。", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "ログインを完了するには DUO を起動し手順に従ってください。" }, - "duoRequiredByOrgForAccount": { - "message": "アカウントには DUO 二段階認証が必要です。" + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "新しいウィンドウで拡張機能を開いてログインを完了してください" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "拡張機能のポップアップ" @@ -2974,10 +2978,6 @@ "message": "このオプションを無視すると、Bitwarden の自動入力メニューとブラウザの自動入力メニューが競合する可能性があります。", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "この操作は Bitwarden 拡張機能を再起動します。このオプションを無視すると、Bitwarden の自動入力メニューとブラウザの自動入力メニューが競合する可能性があります。", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Bitwarden をデフォルトのパスワードマネージャーにする", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 2f3ac899bb3..723f0bbdad9 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 63a62db04c4..2682011e8e1 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index e5e245607e6..f4b60d87dd0 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index e872f0d7fd8..81c95d2e572 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "폴더 선택..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index e6e479cf0d8..26cde9dc2b0 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -561,10 +561,10 @@ "message": "Keisti pagrindinį slaptažodį" }, "changeMasterPasswordConfirmation": { - "message": "Pagrindinį slaptažodį galite pakeisti bitwarden.com žiniatinklio saugykloje. Ar norite dabar apsilankyti svetainėje?" + "message": "Pagrindinį slaptažodį galite pakeisti „bitwarden.com“ žiniatinklio saugykloje. Ar norite dabar apsilankyti svetainėje?" }, "twoStepLoginConfirmation": { - "message": "Prisijungus dviem veiksmais, jūsų paskyra tampa saugesnė, reikalaujant patvirtinti prisijungimą naudojant kitą įrenginį, pvz., Saugos raktą, autentifikavimo programą, SMS, telefono skambutį ar el. Paštą. Dviejų žingsnių prisijungimą galima įjungti „bitwarden.com“ interneto saugykloje. Ar norite dabar apsilankyti svetainėje?" + "message": "Prisijungus dviem veiksmais, jūsų paskyra tampa saugesnė, reikalaujant patvirtinti prisijungimą naudojant kitą įrenginį, pvz., saugos raktą, autentifikavimo programėlę, SMS, telefono skambutį ar el. paštą. Dviejų žingsnių prisijungimą galima įjungti „bitwarden.com“ interneto saugykloje. Ar norite dabar apsilankyti svetainėje?" }, "editedFolder": { "message": "Katalogas atnaujintas" @@ -673,7 +673,7 @@ "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "notificationAddDesc": { - "message": "Ar Bitwarden turėtų įsiminti šį slaptažodį už tave?" + "message": "Ar „Bitwarden“ turėtų įsiminti šį slaptažodį už Jus?" }, "notificationAddSave": { "message": "Išsaugoti" @@ -694,13 +694,13 @@ "message": "Paprašykite išsaugoti naujus prieigos raktus arba prisijungti naudodant saugykloje saugomus prieigos raktus. Taikoma visoms prisijungusioms paskyroms." }, "notificationChangeDesc": { - "message": "Ar nori atnaujinti šį slaptažodį Bitwarden?" + "message": "Ar nori atnaujinti šį slaptažodį „Bitwarden“ programėlėje?" }, "notificationChangeSave": { "message": "Atnaujinti" }, "notificationUnlockDesc": { - "message": "Atrakink savo Bitwarden saugyklą, kad užpildytum automatinio užpildymo užklausą." + "message": "Atrakinkite savo „Bitwarden“ saugyklą, kad užbaigtumėte automatinio užpildymo užklausą." }, "notificationUnlock": { "message": "Atrakinti" @@ -762,7 +762,7 @@ "message": "Šis duomenų exportavimas užšifruoja jūsų duomenis naudodamas jūsų prieigos kodų raktu. Jei jūs kada nuspręsite pakeisti prieigos kodų raktą, jūs turėtumėte per naują eksportuoti duomenis, nes kitaip, jūs negalėsite iššifruoti išeksportuotų duomenų." }, "encExportAccountWarningDesc": { - "message": "Prieigos kodų raktai yra unikalūs kiekvienai Bitwarden vartotojo paskyrai, taigi jums nepavyktų importuoti užkoduotų eksportuotų duomenų į kitą prieigą." + "message": "Paskyros šifravimo raktai yra unikalūs kiekvienai „Bitwarden“ vartotojo paskyrai, todėl negalite importuoti užšifruoto eksportavimo į kitą paskyrą." }, "exportMasterPassword": { "message": "Įveskite pagrindinį slaptažodį norint išsinešti saugyklos duomenis." @@ -774,7 +774,7 @@ "message": "Sužinoti apie organizacijas" }, "learnOrgConfirmation": { - "message": "Bitwarden leidžia jums dalintis savo saugyklos elementais su kitais vartotojais organizacijoje. Ar jūs norėtumėte apsilankyti bitwarden.com puslapyje, kad sužinoti daugiau?" + "message": "„Bitwarden“ leidžia dalytis saugyklos elementais su kitais naudojantis organizacija. Ar norėtumėte apsilankyti „bitwarden.com“ svetainėje ir sužinoti daugiau?" }, "moveToOrganization": { "message": "Perkelti į organizaciją" @@ -853,7 +853,7 @@ "message": "Tvarkyti narystę" }, "premiumManageAlert": { - "message": "Galite tvarkyti savo narystę internete per bitwarden.com. Ar norite aplankyti šį puslapį dabar?" + "message": "Savo narystę galite tvarkyti „bitwarden.com“ žiniatinklio saugykloje. Ar norite apsilankyti svetainėje dabar?" }, "premiumRefresh": { "message": "Atnaujinti narystę" @@ -886,13 +886,13 @@ "message": "Įsigyti Premium" }, "premiumPurchaseAlert": { - "message": "Gali įsigyti Premium narystę bitwarden.com interneto saugykloje. Ar nori aplankyti svetainėje dabar?" + "message": "Galite įsigyti „Premium“ narystę „bitwarden.com“ žiniatinklio saugykloje. Ar norite apsilankyti svetainėje dabar?" }, "premiumCurrentMember": { "message": "Tu esi Premium narys!" }, "premiumCurrentMemberThanks": { - "message": "Dėkojame, kad remiate Bitwarden." + "message": "Dėkojame, kad palaikote „Bitwarden“." }, "premiumPrice": { "message": "Visa tai tik už $PRICE$ / metus!", @@ -1021,7 +1021,7 @@ "message": "Savarankiškai sukurta aplinka" }, "selfHostedEnvironmentFooter": { - "message": "Nurodyk pagrindinį URL adresą savo patalpose esančio Bitwarden diegimo." + "message": "Nurodykite vietinio priglobto „Bitwarden“ diegimo bazinį URL." }, "customEnvironment": { "message": "Individualizuota aplinka" @@ -1481,7 +1481,7 @@ "message": "Silpnas pagrindinis slaptažodis" }, "weakMasterPasswordDesc": { - "message": "Jūsų pasirinktas pagrindinis slaptažodis yra silpnas. Turėtumėte naudoti stiprų pagrindinį slaptažodį (arba slaptafrazę), kad tinkamai apsaugotumėte savo Bitwarden paskyrą. Ar tikrai norite naudoti šį pagrindinį slaptažodį?" + "message": "Jūsų pasirinktas pagrindinis slaptažodis yra silpnas. Turėtumėte naudoti stiprų pagrindinį slaptažodį (arba slaptafrazę), kad tinkamai apsaugotumėte savo „Bitwarden“ paskyrą. Ar tikrai norite naudoti šį pagrindinį slaptažodį?" }, "pin": { "message": "PIN", @@ -1509,7 +1509,7 @@ "message": "Laukiama patvirtinimo iš darbalaukio" }, "awaitDesktopDesc": { - "message": "Patvirtinkite naudodami biometrinius duomenis Bitwarden darbalaukio programoje, kad nustatytumėte naršyklės biometrinius duomenis." + "message": "Patvirtinkite naudodami biometrinius duomenis „Bitwarden“ darbalaukio programoje, kad nustatytumėte naršyklės biometrinius duomenis." }, "lockWithMasterPassOnRestart": { "message": "Užrakinkite pagrindiniu slaptažodžiu paleidus naršyklę iš naujo" @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Pasirinkti aplankalą..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Dėl organizacijos leidimų atnaujinimo, Jums reikia nustatyti pagrindinį slaptažodį.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2168,17 +2172,17 @@ "message": "Sugeneruoti el. pašto slapyvardį su išorine persiuntimo paslauga." }, "hostname": { - "message": "Hostname", + "message": "Pagrindinio kompiuterio vardas", "description": "Part of a URL." }, "apiAccessToken": { - "message": "API Access Token" + "message": "API Prieigos Raktas" }, "apiKey": { "message": "API raktas" }, "ssoKeyConnectorError": { - "message": "Key connector error: make sure key connector is available and working correctly." + "message": "Rakto jungties klaida: įsitikinkite, kad rakto jungtis yra prieinama ir veikia tinkamai." }, "premiumSubcriptionRequired": { "message": "Reikalingas Premium abonementas" @@ -2187,10 +2191,10 @@ "message": "Organizacija suspenduota." }, "disabledOrganizationFilterError": { - "message": "Items in suspended Organizations cannot be accessed. Contact your Organization owner for assistance." + "message": "Elementai esantys suspenduotose Organizacijose yra neprieinami. Susisiekite su savo Organizacijos savininku." }, "loggingInTo": { - "message": "Logging in to $DOMAIN$", + "message": "Prisijungiama prie $DOMAIN$", "placeholders": { "domain": { "content": "$1", @@ -2199,25 +2203,25 @@ } }, "settingsEdited": { - "message": "Settings have been edited" + "message": "Nustatymai buvo paredaguoti" }, "environmentEditedClick": { "message": "Spauskite čia" }, "environmentEditedReset": { - "message": "to reset to pre-configured settings" + "message": "iš naujo nustatyti iš anksto sukonfigūruotus nustatymus" }, "serverVersion": { - "message": "Server version" + "message": "Serverio versija" }, "selfHostedServer": { - "message": "self-hosted" + "message": "savarankiškai sukurtas" }, "thirdParty": { "message": "Trečioji šalis" }, "thirdPartyServerMessage": { - "message": "Connected to third-party server implementation, $SERVERNAME$. Please verify bugs using the official server, or report them to the third-party server.", + "message": "Prisijungta prie trečiosios šalies serverio diegimo $SERVERNAME$. Patikrinkite klaidas naudodami oficialų serverį arba praneškite apie jas trečiosios šalies serveriui.", "placeholders": { "servername": { "content": "$1", @@ -2226,7 +2230,7 @@ } }, "lastSeenOn": { - "message": "last seen on: $DATE$", + "message": "paskutinį kartą matytas: $DATE$", "placeholders": { "date": { "content": "$1", @@ -2256,7 +2260,7 @@ "message": "Prisijungti su įrenginiu turi būti nustatyta Bitwarden aplikacijos nustatymuose. Reikia kito pasirinkimo?" }, "fingerprintPhraseHeader": { - "message": "Fingerprint phrase" + "message": "Pirštų atspaudų frazė" }, "fingerprintMatchInfo": { "message": "Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device." @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Paleisk DUO ir sek veiksmus, kad baigtum prisijungti." }, - "duoRequiredByOrgForAccount": { - "message": "Tavo paskyrai reikalingas DUO dviejų veiksmų prisijungimas." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Atidaryk plėtinį naujame lange, kad užbaigtum prisijungimą." + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Iššokantis plėtinys" @@ -2974,10 +2978,6 @@ "message": "Ignoruojant šią parinktį, gali kilti konfliktų tarp Bitwarden automatinio užpildymo meniu ir naršyklės.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Šis veiksmas iš naujo paleis Bitwarden plėtinį.\nIgnoruojant šią parinktį, gali kilti konfliktų tarp Bitwarden automatinio užpildymo meniu ir naršyklės.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Padaryti Bitwarden savo numatytuoju slaptažodžių tvarkytuvu", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 4aa350a9e7c..e513ef13656 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Izvēlēties mapi..." }, + "noFoldersFound": { + "message": "Nav atrasta neviena mape", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Apvienības atļaujas tika atjauninātas, un tās pieprasa iestatīt galveno paroli.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Jāpalaiž DUO un jāseko soļiem, lai pabeigtu pieteikšanos." }, - "duoRequiredByOrgForAccount": { - "message": "Kontam ir nepieciešama DUO divpakāpju pieteikšanās." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Paplašinājums jāatver jaunā logā, lai pabeigtu pieteikšanos" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Atvērt paplašinājumu atsevišķi" @@ -2974,10 +2978,6 @@ "message": "Šīs iespējas neņemšana vērā var radīt nesaderības starp Bitwarden automātiskās aizpildes izvēlni un pārlūka.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Šī darbība pārsāknēs Bitwarden paplašinājumu. Šīs iespējas neņemšana vērā var radīt nesaderības starp Bitwarden automātiskās aizpildes izvēlni un pārlūka.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Padarīt Bitwarden par noklusējuma paroļu pārvaldnieku", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 00137abee7d..762be4a8ac5 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 812f92c0ef7..ac6b6234d2d 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 63a62db04c4..2682011e8e1 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 08e59cf6fff..044c9635002 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Velg mappe …" }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Gjør Bitwarden til din standard passordbehandler", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 63a62db04c4..2682011e8e1 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 201fd4d84c5..e1ce1999477 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -1180,7 +1180,7 @@ "message": "Naam kaarthouder" }, "number": { - "message": "Kaartummer" + "message": "Kaartnummer" }, "brand": { "message": "Merk" @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Map selecteren..." }, + "noFoldersFound": { + "message": "Geen mappen gevonden", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "duoRequiredForAccount": { + "message": "Jouw account vereist Duo-tweestapsaanmelding." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Open de extensie om in te loggen." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Deze optie negeren kan tot conflicten leiden tussen het automatisch invullen van Bitwarden en dat van je browser.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Deze actie herstart de Bitwarden-extensie. Deze optie negeren kan tot conflicten leiden tussen het automatisch invullen van Bitwarden en dat van je browser.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Maak van Bitwarden je standaardwachtbeheerder", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 63a62db04c4..2682011e8e1 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 63a62db04c4..2682011e8e1 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 44c8241115d..7daffc7ba7f 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Wybierz folder..." }, + "noFoldersFound": { + "message": "Nie znaleziono folderów", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Uprawnienia w Twojej organizacji zostały zaktualizowane, musisz teraz ustawić hasło główne.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Uruchom DUO i wykonaj kroki, aby zakończyć logowanie." }, - "duoRequiredByOrgForAccount": { - "message": "Dwustopniowe logowanie DUO jest wymagane dla Twojego konta." + "duoRequiredForAccount": { + "message": "Dwustopniowe logowanie Duo jest wymagane dla Twojego konta." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Otwórz rozszerzenie w nowym oknie aby zakończyć logowanie" + "popoutTheExtensionToCompleteLogin": { + "message": "Otwórz rozszerzenie w nowym oknie, aby dokończyć logowanie." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignorowanie tej opcji może spowodować konflikty pomiędzy menu autouzupełniania Bitwarden a przeglądarką.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Ta akcja zrestartuje rozszerzenie Bitwarden. Ignorowanie tej opcji może spowodować konflikty pomiędzy menu autouzupełniania Bitwarden a przeglądarką.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Ustaw Bitwarden jako domyślny menedżer haseł", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 21b698f6888..c751cb74133 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Selecionar pasta..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "As permissões da sua organização foram atualizadas, exigindo que você defina uma senha mestra.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 2ddfe4e6843..9972b0b32de 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Selecionar pasta..." }, + "noFoldersFound": { + "message": "Nenhuma pasta encontrada", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "As permissões da sua organização foram atualizadas, exigindo a definição de uma palavra-passe mestra.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2702,19 +2706,19 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicie o DUO e siga os passos para concluir o início de sessão." + "message": "Inicie o Duo e siga os passos para concluir o início de sessão." }, - "duoRequiredByOrgForAccount": { - "message": "A verificação em dois passos DUO é necessária para a sua conta." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Abra a extensão numa nova janela para concluir o início de sessão" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Extensão popout" }, "launchDuo": { - "message": "Iniciar o DUO" + "message": "Iniciar o Duo" }, "importFormatError": { "message": "Os dados não estão formatados corretamente. Por favor, verifique o seu ficheiro de importação e tente novamente." @@ -2974,10 +2978,6 @@ "message": "Ignorar esta opção pode causar conflitos entre o menu de preenchimento automático do Bitwarden e o do seu navegador.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Esta ação reiniciará a extensão Bitwarden. Ignorar esta opção pode causar conflitos entre o menu de preenchimento automático do Bitwarden e o do seu navegador.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Tornar o Bitwarden o seu gestor de palavras-passe predefinido", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 4c12b5351af..80305d6b371 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Selectare folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 37ce639cb97..f9e25dd4d59 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -494,10 +494,10 @@ "message": "Ваш аккаунт создан! Теперь вы можете войти в систему." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Вы успешно авторизовались" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Можете закрыть это окно" }, "masterPassSent": { "message": "Мы отправили вам письмо с подсказкой к мастер-паролю." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Выберите папку..." }, + "noFoldersFound": { + "message": "Папки не найдены", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Права доступа организации были обновлены, требуется установить мастер-пароль.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2702,19 +2706,19 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустите DUO и следуйте шагам для завершения авторизации." + "message": "Запустите Duo и следуйте шагам для завершения авторизации." }, - "duoRequiredByOrgForAccount": { - "message": "Для вашего аккаунта требуется двухэтапная аутентификация DUO." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Откройте расширение в новом окне, чтобы завершить авторизацию" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Открепить расширение" }, "launchDuo": { - "message": "Запустить DUO" + "message": "Запустить Duo" }, "importFormatError": { "message": "Формат данных некорректен. Проверьте импортируемый файл и повторите попытку." @@ -2974,10 +2978,6 @@ "message": "Отключение этого параметра может привести к конфликту между меню автозаполнения Bitwarden и вашим браузером.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Это действие перезапустит расширение Bitwarden. Игнорирование этой опции может привести к конфликту между меню автозаполнения Bitwarden и вашим браузером.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Сделать Bitwarden менеджером паролей по умолчанию", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 312e908f658..07b0bb78e4a 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "ෆෝල්ඩරය තෝරන්න..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 9b6cf7b99f7..d1ac6409f31 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Vybrať priečinok..." }, + "noFoldersFound": { + "message": "Nenašli sa žiadne priečinky", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Povolenia vašej organizácie boli aktualizované, čo si vyžaduje nastavenie hlavného hesla.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Spustite DUO a postupujte podľa pokynov na dokončenie prihlásenia." }, - "duoRequiredByOrgForAccount": { - "message": "Pre váš účet je potrebné dvojstupňové prihlásenie DUO." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Na dokončenie prihlásenia otvorte rozšírenie v novom okne" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Zobraziť rozšírenie v novom okne" @@ -2974,10 +2978,6 @@ "message": "Ak nenastavíte túto možnosť, môže to spôsobiť konflikty medzi ponukou automatického vypĺňania Bitwardenu a ponukou vášho prehliadača.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Táto akcia reštartuje rozšírenie Bitwarden. Ignorovanie tejto možnosti môže spôsobiť konflikty medzi ponukou automatického vypĺňania Bitwarden a ponukou prehliadača.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Nastaviť Bitwarden ako predvolený správca hesiel", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 23e4eca4d6a..abe3b056692 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Izberi mapo..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index b6be31db465..b188b9c8cdf 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -494,10 +494,10 @@ "message": "Ваш налог је креиран! Сада се можете пријавити." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Успешно сте се пријавили" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Можете затворити овај прозор" }, "masterPassSent": { "message": "Послали смо Вам поруку са саветом главне лозинке." @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Изаберите фасциклу..." }, + "noFoldersFound": { + "message": "Нису пронађене фасцикле", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Дозволе за вашу организацију су ажуриране, што захтева да поставите главну лозинку.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Покренути DUO и пратите кораке да бисте завршили пријављивање." }, - "duoRequiredByOrgForAccount": { - "message": "DUO пријава у два корака је потребна за ваш налог." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Отворите екстензију у новом прозору да бисте завршили пријаву" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Игнорисање ове опције може довести до сукоба између љутопуњења Bitwarden-а и вашег прегледача.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Ова акција ће поново покренути ектензију Bitwarden-а. Игнорисање ове опције може довести до сукоба између љутопуњења Bitwarden-а и вашег прегледача.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Урадите да Bitwarden буде ваш подразумевани менаџер лозинки", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 35b7ae79cc1..4d7dc9b8143 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -688,10 +688,10 @@ "message": "Ask to update a login's password when a change is detected on a website. Applies to all logged in accounts." }, "enableUsePasskeys": { - "message": "Be om att spara och använda nycklar" + "message": "Be om att spara och använda lösennycklar" }, "usePasskeysDesc": { - "message": "Be om att spara nya nycklar eller logga in med nycklar som lagras i ditt valv. Gäller för alla inloggade konton." + "message": "Be om att spara nya lösennycklar eller logga in med nycklar som lagras i ditt valv. Gäller för alla inloggade konton." }, "notificationChangeDesc": { "message": "Vill du uppdatera det här lösenordet i Bitwarden?" @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Välj mapp…" }, + "noFoldersFound": { + "message": "Inga mappar hittades", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2788,25 +2792,25 @@ "message": "Confirm file password" }, "typePasskey": { - "message": "Nyckel" + "message": "Lösennyckel" }, "passkeyNotCopied": { - "message": "Nyckeln kommer inte kopieras" + "message": "Lösennyckeln kommer inte kopieras" }, "passkeyNotCopiedAlert": { - "message": "Nyckeln kommer inte att kopieras till det klonade objektet. Vill du fortsätta klona det här objektet?" + "message": "Lösennyckeln kommer inte att kopieras till det klonade objektet. Vill du fortsätta klona det här objektet?" }, "passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": { "message": "Verifiering krävs av den initierande webbplatsen. Denna funktion är ännu inte implementerad för konton utan huvudlösenord." }, "logInWithPasskey": { - "message": "Logga in med nyckel?" + "message": "Logga in med lösennyckel?" }, "passkeyAlreadyExists": { - "message": "En nyckel finns redan för detta program." + "message": "En lösennyckel finns redan för detta program." }, "noPasskeysFoundForThisApplication": { - "message": "Inga nycklar hittades för detta program." + "message": "Inga lösennycklar hittades för detta program." }, "noMatchingPasskeyLogin": { "message": "Det finns ingen matchande inloggning för denna webbplats." @@ -2815,28 +2819,28 @@ "message": "Bekräfta" }, "savePasskey": { - "message": "Spara nyckel" + "message": "Spara lösennyckel" }, "savePasskeyNewLogin": { - "message": "Spara nyckel som ny inloggning" + "message": "Spara lösennyckel som ny inloggning" }, "choosePasskey": { - "message": "Välj en inloggning för att spara denna nyckel till" + "message": "Välj en inloggning för att spara denna lösennyckel till" }, "passkeyItem": { - "message": "Nyckelobjekt" + "message": "Lösennyckelobjekt" }, "overwritePasskey": { - "message": "Skriv över nyckel?" + "message": "Skriv över lösennyckel?" }, "overwritePasskeyAlert": { - "message": "Detta objekt innehåller redan en nyckel. Är du säker på att du vill skriva över nuvarande nyckeln?" + "message": "Detta objekt innehåller redan en lösennyckel. Är du säker på att du vill skriva över nuvarande lösennyckeln?" }, "featureNotSupported": { "message": "Feature not yet supported" }, "yourPasskeyIsLocked": { - "message": "Autentisering krävs för att använda nyckel. Verifiera din identitet för att fortsätta." + "message": "Autentisering krävs för att använda lösennyckel. Verifiera din identitet för att fortsätta." }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Låt Bitwarden hantera lösenord som standard", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 63a62db04c4..2682011e8e1 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 76ee4fb0bdb..db78221a874 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Select folder..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 03b26b9ca5c..2f9321a9559 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Klasör seç..." }, + "noFoldersFound": { + "message": "Herhangi bir klasör bulunamadı", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Kuruluş izinleriniz güncellendi ve bir ana parola belirlemeniz gerekiyor.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "DUO'yu başlatın ve oturum açmayı tamamlamak için adımları izleyin." }, - "duoRequiredByOrgForAccount": { - "message": "Hesabınız için DUO iki adımlı giriş gereklidir." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Oturum açma işlemini tamamlamak için uzantıyı yeni bir pencerede açın" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout uzantısı" @@ -2974,10 +2978,6 @@ "message": "Bu seçeneğin göz ardı edilmesi, Bitwarden otomatik doldurma menüsü ile tarayıcınızınki arasında çakışmalara neden olabilir.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Bu eylem Bitwarden uzantısını yeniden başlatacaktır. Bu seçeneğin göz ardı edilmesi, Bitwarden otomatik doldurma menüsü ile tarayıcınızın arasında çakışmalara neden olabilir.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Bitwarden'ı varsayılan şifre yöneticiniz yapın", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 0f8b4b2e58a..6de0a8b570f 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Обрати теку..." }, + "noFoldersFound": { + "message": "Тек не знайдено", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Оновлено дозволи вашої організації – вимагається встановлення головного пароля.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Запустіть Duo і виконайте дії для завершення входу." }, - "duoRequiredByOrgForAccount": { - "message": "Для вашого облікового запису необхідна двоетапна перевірка з Duo." + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Відкрийте розширення у новому вікні, щоб завершити вхід" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Відкріпити вікно розширення" @@ -2974,10 +2978,6 @@ "message": "Якщо ігнорувати цей параметр, можуть виникнути конфлікти автозаповнення між Bitwarden і браузером.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "Ця дія призведе до перезапуску розширення Bitwarden. Якщо ігнорувати цей параметр, можуть виникнути конфлікти автозаповнення між Bitwarden і браузером.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Зробити Bitwarden типовим менеджером паролів", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 03b18691047..33822362d8d 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "Chọn thư mục..." }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "Your organization permissions were updated, requiring you to set a master password.", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 970021d0527..e681883c2bb 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -494,10 +494,10 @@ "message": "您的新账户已创建!您现在可以登录了。" }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "您已成功登录" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "您可以关闭此窗口" }, "masterPassSent": { "message": "我们已经为您发送了包含主密码提示的邮件。" @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "选择文件夹..." }, + "noFoldersFound": { + "message": "找不到文件夹", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "您的组织权限已更新,要求您设置主密码。", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "启动 DUO 并按照步骤完成登录。" }, - "duoRequiredByOrgForAccount": { - "message": "您的账户需要 DUO 两步登录。" + "duoRequiredForAccount": { + "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "在新窗口中打开扩展以完成登录" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "弹出扩展" @@ -2974,10 +2978,6 @@ "message": "忽略此设置可能会导致 Bitwarden 自动填充菜单与浏览器自带功能产生冲突。", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "此操作将重启 Bitwarden 扩展。忽略此选项可能会在 Bitwarden 自动填充菜单和您的浏览器自带功能之间产生冲突。", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "将 Bitwarden 设置为您的默认密码管理器?", "description": "Label for the setting that allows overriding the default browser autofill settings" diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 783a6667073..3157314e12b 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -2004,6 +2004,10 @@ "selectFolder": { "message": "選擇資料夾⋯" }, + "noFoldersFound": { + "message": "No folders found", + "description": "Used as a message within the notification bar when no folders are found" + }, "orgPermissionsUpdatedMustSetPassword": { "message": "您的組織權限已更新,需要您設定主密碼。", "description": "Used as a card title description on the set password page to explain why the user is there" @@ -2704,11 +2708,11 @@ "launchDuoAndFollowStepsToFinishLoggingIn": { "message": "Launch Duo and follow the steps to finish logging in." }, - "duoRequiredByOrgForAccount": { + "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "openExtensionInNewWindowToCompleteLogin": { - "message": "Open the extension in a new window to complete login" + "popoutTheExtensionToCompleteLogin": { + "message": "Popout the extension to complete login." }, "popoutExtension": { "message": "Popout extension" @@ -2974,10 +2978,6 @@ "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, - "overrideDefaultBrowserAutofillPrivacyRequiredDescription": { - "message": "This action will restart the Bitwarden extension. Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", - "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" - }, "overrideDefaultBrowserAutoFillSettings": { "message": "Make Bitwarden your default password manager", "description": "Label for the setting that allows overriding the default browser autofill settings" From 233c93627dc876e2442a093d3451ac59bb40b22b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 12:06:23 +0000 Subject: [PATCH 004/124] Autosync the updated translations (#8060) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/az/messages.json | 42 ++++++++++---------- apps/desktop/src/locales/bg/messages.json | 10 ++--- apps/desktop/src/locales/ca/messages.json | 10 ++--- apps/desktop/src/locales/cs/messages.json | 10 ++--- apps/desktop/src/locales/da/messages.json | 10 ++--- apps/desktop/src/locales/de/messages.json | 10 ++--- apps/desktop/src/locales/fi/messages.json | 10 ++--- apps/desktop/src/locales/hu/messages.json | 10 ++--- apps/desktop/src/locales/it/messages.json | 10 ++--- apps/desktop/src/locales/ja/messages.json | 10 ++--- apps/desktop/src/locales/lv/messages.json | 10 ++--- apps/desktop/src/locales/pl/messages.json | 10 ++--- apps/desktop/src/locales/ru/messages.json | 10 ++--- apps/desktop/src/locales/sk/messages.json | 10 ++--- apps/desktop/src/locales/sr/messages.json | 10 ++--- apps/desktop/src/locales/sv/messages.json | 2 +- apps/desktop/src/locales/tr/messages.json | 10 ++--- apps/desktop/src/locales/uk/messages.json | 10 ++--- apps/desktop/src/locales/zh_CN/messages.json | 12 +++--- 19 files changed, 108 insertions(+), 108 deletions(-) diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index 4ba44469127..65356202fef 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -561,10 +561,10 @@ "message": "Yeni hesabınız yaradıldı! İndi giriş edə bilərsiniz." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Uğurla giriş etdiniz" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Bu pəncərəni bağlaya bilərsiniz" }, "masterPassSent": { "message": "Ana parol məsləhətini ehtiva edən bir e-poçt göndərdik." @@ -1554,7 +1554,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { - "message": "Verification required", + "message": "Doğrulama tələb olunur", "description": "Default title for the user verification dialog." }, "currentMasterPass": { @@ -1883,40 +1883,40 @@ "message": "Ana parolunuz təşkilatınızdakı siyasətlərdən birinə və ya bir neçəsinə uyğun gəlmir. Anbara müraciət üçün ana parolunuzu indi güncəlləməlisiniz. Davam etsəniz, hazırkı seansdan çıxış etmiş və təkrar giriş etməli olacaqsınız. Digər cihazlardakı aktiv seanslar bir saata qədər aktiv qalmağa davam edə bilər." }, "tryAgain": { - "message": "Try again" + "message": "Yenidən sına" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Bu əməliyyat üçün doğrulama tələb olunur. Davam etmək üçün bir PIN təyin edin." }, "setPin": { - "message": "Set PIN" + "message": "PIN təyin et" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Biometriklə doğrula" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Təsdiq gözlənilir" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Biometrik tamamlana bilmədi." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Fərqli bir üsul lazımdır?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Ana parolu istifadə et" }, "usePin": { - "message": "Use PIN" + "message": "PIN-i istifadə et" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Biometrik istifadə et" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "E-poçtunuza göndərilmiş doğrulama kodunu daxil edin." }, "resendCode": { - "message": "Resend code" + "message": "Kodu təkrar göndər" }, "hours": { "message": "Saat" @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Duo-nu başladın və giriş prosesini tamamlamaq üçün addımları izləyin." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Hesabınız üçün Duo iki addımlı giriş tələb olunur." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Duo-nu brauzerdə başlat" }, "importFormatError": { "message": "Data doğru format edilməyib. Lütfən daxilə köçürmə faylınızı yoxlayıb yenidən sınayın." @@ -2621,13 +2621,13 @@ "message": "Yanlış istifadəçi adı və ya parol" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Yanlış parol" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Yanlış kod" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "Yanlış PIN" }, "multifactorAuthenticationFailed": { "message": "Çox faktorlu kimlik doğrulama uğursuz oldu" diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index 00d4fc56edf..35c680345c7 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -561,10 +561,10 @@ "message": "Абонаментът ви бе създаден. Вече можете да се впишете." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Вписахте се успешно" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Може да затворите този прозорец" }, "masterPassSent": { "message": "Изпратили сме ви е-писмо с подсказка за главната ви парола." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Стартирайте Duo и следвайте инструкциите, за да завършите вписването." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Вашата регистрация изисква двустепенно удостоверяване чрез Duo." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Стартирайте Duo в браузъра" }, "importFormatError": { "message": "Данните са в неправилен формат. Проверете файла за внасяне и пробвайте отново." diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index 8bdd3da1031..8ae932bfa64 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -561,10 +561,10 @@ "message": "El vostre compte s'ha creat correctament. Ara ja podeu iniciar sessió." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Heu iniciat sessió correctament" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Podeu tancar aquesta finestra" }, "masterPassSent": { "message": "Hem enviat un correu electrònic amb la vostra contrasenya mestra." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Inicieu DUO i seguiu els passos per finalitzar la sessió." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Es requereix l'inici de sessió en dos passos de DUO al vostre compte." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Inicia Duo al navegador" }, "importFormatError": { "message": "Les dades no estan formatades correctament. Comproveu el fitxer d'importació i torneu-ho a provar." diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 7810f226cb9..660b626749d 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -561,10 +561,10 @@ "message": "Váš účet byl vytvořen! Můžete se přihlásit." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Byli jste úspěšně přihlášeni" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Toto okno můžete zavřít" }, "masterPassSent": { "message": "Poslali jsme vám e-mail s nápovědou k hlavnímu heslu." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Spusťte DUO a pro dokončení přihlášení postupujte podle kroků." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Pro Váš účet je vyžadováno dvoufázové přihlášení DUO." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Spustit DUO v prohlížeči" }, "importFormatError": { "message": "Data nemají správný formát. Zkontrolujte importovaný soubor a zkuste to znovu." diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index a7546018684..c3c42e2904f 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -561,10 +561,10 @@ "message": "Den nye konto er oprettet! Der kan nu logges ind." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Du er nu logget ind" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Dette vindue kan nu lukkes" }, "masterPassSent": { "message": "Der er sendt en e-mail til dig med dit hovedadgangskodetip." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Start Duo og følg trinnene for at fuldføre indlogningen." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Duo totrinsindlogning kræves for kontoen." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Start Duo i webbrowser" }, "importFormatError": { "message": "Data er ikke korrekt formateret. Tjek importfilen og forsøg igen." diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index d9d2ec3d530..27e6b048cc0 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -561,10 +561,10 @@ "message": "Dein neues Konto wurde erstellt! Du kannst dich jetzt anmelden." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Du hast dich erfolgreich angemeldet." }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Du kannst dieses Fenster schließen." }, "masterPassSent": { "message": "Wir haben dir eine E-Mail mit dem Master-Passwort-Hinweis gesendet." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Starte DUO und folge den Schritten, um die Anmeldung abzuschließen." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Für dein Konto ist die DUO Zwei-Faktor-Authentifizierung erforderlich." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Duo im Browser starten" }, "importFormatError": { "message": "Die Daten sind nicht richtig formatiert. Kontrolliere bitte deine Import-Datei und versuche es erneut." diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 9f0dd36cae2..d04c13d34e4 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -561,10 +561,10 @@ "message": "Uusi käyttäjätilisi on luotu! Voit nyt kirjautua sisään." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Kirjautuminen onnistui" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Voit sulkea tämän ikkunan" }, "masterPassSent": { "message": "Lähetimme pääsalasanasi vihjeen sinulle sähköpostitse." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Tilillesi kirjautuminen vaatii Duo-vahvistuksen." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Avaa Duo verkkoselaimessa" }, "importFormatError": { "message": "Tietoja ei ole muotoiltu oikein. Tarkista tuotava tiedosto ja yritä uudelleen." diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index cba6aa95c25..33aab75339f 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -561,10 +561,10 @@ "message": "A fiók létrehozásra került. Most már be lehet jelentkezni." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "A bejelentkezés sikeres volt." }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Most már bezárható ez az ablak." }, "masterPassSent": { "message": "Elküldtünk neked egy emailt a mesterjelszó emlékeztetővel." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Indítsuk el a DUO-t és kövessük a lépéseket a bejelentkezés befejezéséhez." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "A fiókhoz kétlépcsős DUO bejelentkezés szükséges." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "A Duo elindítása a böngészőben" }, "importFormatError": { "message": "Az adatok nincsenek megfelelően formázva. Ellenőrizzük az importálás fájlt és próbáljuk újra." diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index 8b2a51ddb08..77100fc9281 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -561,10 +561,10 @@ "message": "Il tuo nuovo account è stato creato! Ora puoi eseguire l'accesso." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Hai effettuato l'accesso" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Puoi chiudere questa finestra" }, "masterPassSent": { "message": "Ti abbiamo inviato un'email con il tuo suggerimento per la password principale." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Avvia Duo e segui i passaggi per finire di accedere." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Per il tuo account è richiesta la verifica in due passaggi Duo." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Avvia Duo nel browser" }, "importFormatError": { "message": "I dati non sono formattati correttamente. Controlla il file di importazione e riprova." diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 6ed9b9ad6c7..033169c9a8d 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -561,10 +561,10 @@ "message": "新しいアカウントを作成しました!今すぐログインできます。" }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "ログインに成功しました" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "ウィンドウを閉じて大丈夫です" }, "masterPassSent": { "message": "あなたのマスターパスワードのヒントを記載したメールを送信しました。" @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "ログインを完了するには Duo を起動し手順に従ってください。" }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "アカウントには Duo 二段階認証が必要です。" }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "ブラウザで Duo を起動" }, "importFormatError": { "message": "データが正しい形式ではありません。インポートするファイルを確認してやり直してください。" diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index d57e6e96aa7..b26f9abdf8a 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -561,10 +561,10 @@ "message": "Jaunais konts ir izveidots. Tagad vari pieteikties." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Pieteikšanās bija veiksmīga" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Šo logu var aizvērt" }, "masterPassSent": { "message": "Mēs nosūtījām galvenās paroles norādi e-pastā." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Jāpalaiž Duo un jāseko soļiem, lai pabeigtu pieteikšanos." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Kontam ir nepieciešama Duo divpakāpju pieteikšanās." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Palaist Duo pārlūkā" }, "importFormatError": { "message": "Dati nav pareizi formatēti. Lūgums pārbaudīt ievietošanas datni un mēģināt vēlreiz." diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index 89b5a3bf05e..862b7484e43 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -561,10 +561,10 @@ "message": "Konto zostało utworzone! Teraz możesz się zalogować." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Zalogowałeś się pomyślnie" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Możesz zamknąć to okno" }, "masterPassSent": { "message": "Wysłaliśmy Tobie wiadomość e-mail z podpowiedzią do hasła głównego." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Uruchom Duo i wykonaj kroki, aby zakończyć logowanie." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Dwustopniowe logowanie Duo jest wymagane dla Twojego konta." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Uruchom Duo w przeglądarce" }, "importFormatError": { "message": "Dane nie są poprawnie sformatowane. Sprawdź importowany plik i spróbuj ponownie." diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index d25ed4774f4..693dd44ca24 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -561,10 +561,10 @@ "message": "Аккаунт создан! Теперь вы можете войти в систему." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Вы успешно авторизовались" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Можете закрыть это окно" }, "masterPassSent": { "message": "Мы отправили вам письмо с подсказкой к мастер-паролю." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Запустите Duo и следуйте шагам для завершения авторизации." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Для вашего аккаунта требуется двухэтапная аутентификация Duo." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Запустить Duo в браузере" }, "importFormatError": { "message": "Формат данных некорректен. Проверьте импортируемый файл и повторите попытку." diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 7cc8c37f7c0..7d7f9d8f3c1 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -561,10 +561,10 @@ "message": "Váš nový účet bol vytvorený! Teraz sa môžete prihlásiť." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Úspešne ste sa prihlásili" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Toto okno môžete zavrieť" }, "masterPassSent": { "message": "Emailom sme vám poslali nápoveď k hlavnému heslu." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Spustite DuO a postupujte podľa pokynov na dokončenie prihlásenia." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Pre váš účet je potrebné dvojstupňové prihlásenie Duo." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Spustiť Duo v prehliadači" }, "importFormatError": { "message": "Dáta nie sú správne formátované. Prosím, overte importovaný súbor a skúste to znova." diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 012a8e4f468..dd709ddc6bb 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -561,10 +561,10 @@ "message": "Ваш налог је креиран! Сада се можете пријавити." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Успешно сте се пријавили" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Можете затворити овај прозор" }, "masterPassSent": { "message": "Послали смо Вам поруку са саветом главне лозинке." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Покренути Duo и пратите кораке да бисте завршили пријављивање." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Duo пријава у два корака је потребна за ваш налог." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Покренути Duo у претраживачу" }, "importFormatError": { "message": "Подаци нису правилно форматирани. Проверите датотеку за увоз и покушајте поново." diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index b9732c92af6..5f0c7a95fcb 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -564,7 +564,7 @@ "message": "You successfully logged in" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Du kan stänga detta fönster" }, "masterPassSent": { "message": "Vi har skickat ett e-postmeddelande till dig med din huvudlösenordsledtråd." diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 3861d5c8926..3064ea7fbcd 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -561,10 +561,10 @@ "message": "Yeni hesabınız oluşturuldu! Şimdi giriş yapabilirsiniz." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Başarıyla giriş yaptınız" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Bu pencereyi kapatabilirsiniz" }, "masterPassSent": { "message": "Size ana parolanızın ipucunu içeren bir e-posta gönderdik." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Duo'yu başlatın ve oturum açmayı tamamlamak için adımları izleyin." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Hesabınız için Duo iki adımlı giriş gereklidir." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Duo'yu Tarayıcıda Başlat" }, "importFormatError": { "message": "Veriler doğru biçimlendirilmemiş. Lütfen içe aktarma dosyanızı kontrol edin ve tekrar deneyin." diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 844aaa4aca8..68977d4d0b8 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -561,10 +561,10 @@ "message": "Ваш обліковий запис створений! Тепер ви можете увійти." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Ви успішно увійшли в систему" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Можете закрити це вікно" }, "masterPassSent": { "message": "Ми надіслали вам лист з підказкою для головного пароля." @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Запустіть Duo і виконайте дії для завершення входу." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "Для вашого облікового запису необхідна двоетапна перевірка з Duo." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Запустити Duo в браузері" }, "importFormatError": { "message": "Дані мають некоректне форматування. Перевірте файл імпорту і спробуйте знову." diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 167213c94c0..31a1e42a88c 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -561,10 +561,10 @@ "message": "您的新账户已创建!您现在可以登录了。" }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "您已成功登录" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "您可以关闭此窗口" }, "masterPassSent": { "message": "我们已经为您发送了包含主密码提示的邮件。" @@ -2532,13 +2532,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "启动 Duo 然后按照步骤完成登录。" }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "您的账户需要 Duo 两步登录。" }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "在浏览器中启动 Duo" }, "importFormatError": { "message": "数据格式不正确。请检查您的导入文件然后重试。" @@ -2685,7 +2685,7 @@ "message": "将与您的 LastPass 账户关联的 YubiKey 插入计算机的 USB 端口,然后触摸其按钮。" }, "commonImportFormats": { - "message": "Common formats", + "message": "通用格式", "description": "Label indicating the most common import formats" } } From 071959317c0bc7dfca03b3eed418864eb0658ac6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:10:37 +0100 Subject: [PATCH 005/124] [PM-6435] [deps] Platform (CL): Update @storybook/addon-designs to v7.0.9 (#8066) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30a5d44715d..732eb374ac6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,7 +86,7 @@ "@ngtools/webpack": "16.2.11", "@storybook/addon-a11y": "7.6.17", "@storybook/addon-actions": "7.6.17", - "@storybook/addon-designs": "7.0.7", + "@storybook/addon-designs": "7.0.9", "@storybook/addon-essentials": "7.6.17", "@storybook/addon-interactions": "7.6.17", "@storybook/addon-links": "7.6.17", @@ -7176,9 +7176,9 @@ } }, "node_modules/@storybook/addon-designs": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-designs/-/addon-designs-7.0.7.tgz", - "integrity": "sha512-4Ec85kgv/r55Zh5xOHSIq7b9h7PyYhavMpwLmjpzeOkEdFwiNM9KCTK8SE58yCXzbkrw1JIGb3+FAWfR5JfK5g==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@storybook/addon-designs/-/addon-designs-7.0.9.tgz", + "integrity": "sha512-xJdw1/FgkC8ovTdRIL5FyEJaXtF1XPxsb6rsl2jByG+8tXyM0PJ/yFEkBrqn35Dei2i4N7x8EHXFd8DnzriBRg==", "dev": true, "dependencies": { "@figspec/react": "^1.0.0" diff --git a/package.json b/package.json index 0f15610a860..79fd465dfba 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@ngtools/webpack": "16.2.11", "@storybook/addon-a11y": "7.6.17", "@storybook/addon-actions": "7.6.17", - "@storybook/addon-designs": "7.0.7", + "@storybook/addon-designs": "7.0.9", "@storybook/addon-essentials": "7.6.17", "@storybook/addon-interactions": "7.6.17", "@storybook/addon-links": "7.6.17", From 19a373d87e21a7edb03faa28b7b154afd1c082a6 Mon Sep 17 00:00:00 2001 From: Jake Fink Date: Fri, 23 Feb 2024 08:48:15 -0500 Subject: [PATCH 006/124] [PM-6211] Create key generation service (#7939) * create key generation service * replace old key generation service and add references * use key generation service in key connector service * use key generation service in send service * user key generation service in access service * use key generation service in device trust service * fix tests * fix browser * add createKeyFromMaterial and tests * create ephemeral key * fix tests * rename method and add returns docs * ignore material in destructure * modify test * specify material as key material * pull out magic strings to properties * make salt optional and generate if not provided * fix test * fix parameters * update docs to include link to HKDF rfc --- .../device-trust-crypto-service.factory.ts | 6 ++ .../key-connector-service.factory.ts | 12 +-- .../browser/src/background/main.background.ts | 15 ++- .../service-factories/send-service.factory.ts | 8 +- .../crypto-service.factory.ts | 6 ++ .../key-generation-service.factory.ts | 7 +- .../abstract-key-generation.service.ts | 5 - .../services/key-generation.service.ts | 20 ---- ...cal-backed-session-storage.service.spec.ts | 10 +- .../local-backed-session-storage.service.ts | 15 ++- .../src/popup/services/services.module.ts | 5 +- apps/cli/src/bw.ts | 11 +- .../src/app/services/services.module.ts | 2 + .../services/electron-crypto.service.spec.ts | 3 + .../services/electron-crypto.service.ts | 3 + .../service-accounts/access/access.service.ts | 20 ++-- .../src/services/jslib-services.module.ts | 13 ++- ...ice-trust-crypto.service.implementation.ts | 8 +- .../device-trust-crypto.service.spec.ts | 14 ++- .../auth/services/key-connector.service.ts | 8 +- .../abstractions/key-generation.service.ts | 59 ++++++++++ .../platform/services/crypto.service.spec.ts | 3 + .../src/platform/services/crypto.service.ts | 79 ++++---------- .../services/key-generation.service.spec.ts | 102 ++++++++++++++++++ .../services/key-generation.service.ts | 85 +++++++++++++++ .../tools/send/services/send.service.spec.ts | 6 +- .../src/tools/send/services/send.service.ts | 25 +++-- 27 files changed, 401 insertions(+), 149 deletions(-) delete mode 100644 apps/browser/src/platform/services/abstractions/abstract-key-generation.service.ts delete mode 100644 apps/browser/src/platform/services/key-generation.service.ts create mode 100644 libs/common/src/platform/abstractions/key-generation.service.ts create mode 100644 libs/common/src/platform/services/key-generation.service.spec.ts create mode 100644 libs/common/src/platform/services/key-generation.service.ts diff --git a/apps/browser/src/auth/background/service-factories/device-trust-crypto-service.factory.ts b/apps/browser/src/auth/background/service-factories/device-trust-crypto-service.factory.ts index 8458c40b9bb..6b8d3c09e33 100644 --- a/apps/browser/src/auth/background/service-factories/device-trust-crypto-service.factory.ts +++ b/apps/browser/src/auth/background/service-factories/device-trust-crypto-service.factory.ts @@ -30,6 +30,10 @@ import { I18nServiceInitOptions, i18nServiceFactory, } from "../../../platform/background/service-factories/i18n-service.factory"; +import { + KeyGenerationServiceInitOptions, + keyGenerationServiceFactory, +} from "../../../platform/background/service-factories/key-generation-service.factory"; import { PlatformUtilsServiceInitOptions, platformUtilsServiceFactory, @@ -42,6 +46,7 @@ import { type DeviceTrustCryptoServiceFactoryOptions = FactoryOptions; export type DeviceTrustCryptoServiceInitOptions = DeviceTrustCryptoServiceFactoryOptions & + KeyGenerationServiceInitOptions & CryptoFunctionServiceInitOptions & CryptoServiceInitOptions & EncryptServiceInitOptions & @@ -61,6 +66,7 @@ export function deviceTrustCryptoServiceFactory( opts, async () => new DeviceTrustCryptoService( + await keyGenerationServiceFactory(cache, opts), await cryptoFunctionServiceFactory(cache, opts), await cryptoServiceFactory(cache, opts), await encryptServiceFactory(cache, opts), diff --git a/apps/browser/src/auth/background/service-factories/key-connector-service.factory.ts b/apps/browser/src/auth/background/service-factories/key-connector-service.factory.ts index 625a14e30ea..5fd1866c830 100644 --- a/apps/browser/src/auth/background/service-factories/key-connector-service.factory.ts +++ b/apps/browser/src/auth/background/service-factories/key-connector-service.factory.ts @@ -9,10 +9,6 @@ import { apiServiceFactory, ApiServiceInitOptions, } from "../../../platform/background/service-factories/api-service.factory"; -import { - CryptoFunctionServiceInitOptions, - cryptoFunctionServiceFactory, -} from "../../../platform/background/service-factories/crypto-function-service.factory"; import { CryptoServiceInitOptions, cryptoServiceFactory, @@ -22,6 +18,10 @@ import { CachedServices, factory, } from "../../../platform/background/service-factories/factory-options"; +import { + KeyGenerationServiceInitOptions, + keyGenerationServiceFactory, +} from "../../../platform/background/service-factories/key-generation-service.factory"; import { logServiceFactory, LogServiceInitOptions, @@ -46,7 +46,7 @@ export type KeyConnectorServiceInitOptions = KeyConnectorServiceFactoryOptions & TokenServiceInitOptions & LogServiceInitOptions & OrganizationServiceInitOptions & - CryptoFunctionServiceInitOptions; + KeyGenerationServiceInitOptions; export function keyConnectorServiceFactory( cache: { keyConnectorService?: AbstractKeyConnectorService } & CachedServices, @@ -64,7 +64,7 @@ export function keyConnectorServiceFactory( await tokenServiceFactory(cache, opts), await logServiceFactory(cache, opts), await organizationServiceFactory(cache, opts), - await cryptoFunctionServiceFactory(cache, opts), + await keyGenerationServiceFactory(cache, opts), opts.keyConnectorServiceOptions.logoutCallback, ), ); diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index bdc9d21d91a..3df24d40fe1 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -54,6 +54,7 @@ import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/pla import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { FileUploadService as FileUploadServiceAbstraction } from "@bitwarden/common/platform/abstractions/file-upload/file-upload.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -72,6 +73,7 @@ import { ContainerService } from "@bitwarden/common/platform/services/container. import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation"; import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation"; import { FileUploadService } from "@bitwarden/common/platform/services/file-upload/file-upload.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/services/key-generation.service"; import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service"; import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service"; import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner"; @@ -180,7 +182,6 @@ import BrowserMessagingPrivateModeBackgroundService from "../platform/services/b import BrowserMessagingService from "../platform/services/browser-messaging.service"; import BrowserPlatformUtilsService from "../platform/services/browser-platform-utils.service"; import { BrowserStateService } from "../platform/services/browser-state.service"; -import { KeyGenerationService } from "../platform/services/key-generation.service"; import { LocalBackedSessionStorageService } from "../platform/services/local-backed-session-storage.service"; import { BackgroundDerivedStateProvider } from "../platform/state/background-derived-state.provider"; import { BackgroundMemoryStorageService } from "../platform/storage/background-memory-storage.service"; @@ -207,6 +208,7 @@ export default class MainBackground { i18nService: I18nServiceAbstraction; platformUtilsService: PlatformUtilsServiceAbstraction; logService: LogServiceAbstraction; + keyGenerationService: KeyGenerationServiceAbstraction; cryptoService: CryptoServiceAbstraction; cryptoFunctionService: CryptoFunctionServiceAbstraction; tokenService: TokenServiceAbstraction; @@ -326,6 +328,7 @@ export default class MainBackground { ? new BrowserMessagingPrivateModeBackgroundService() : new BrowserMessagingService(); this.logService = new ConsoleLogService(false); + this.keyGenerationService = new KeyGenerationService(this.cryptoFunctionService); this.cryptoFunctionService = new WebCryptoFunctionService(self); this.storageService = new BrowserLocalStorageService(); this.secureStorageService = new BrowserLocalStorageService(); @@ -333,14 +336,14 @@ export default class MainBackground { BrowserApi.manifestVersion === 3 ? new LocalBackedSessionStorageService( new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false), - new KeyGenerationService(this.cryptoFunctionService), + this.keyGenerationService, ) : new MemoryStorageService(); this.memoryStorageForStateProviders = BrowserApi.manifestVersion === 3 ? new LocalBackedSessionStorageService( new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false), - new KeyGenerationService(this.cryptoFunctionService), + this.keyGenerationService, ) : new BackgroundMemoryStorageService(); this.globalStateProvider = new DefaultGlobalStateProvider( @@ -426,6 +429,7 @@ export default class MainBackground { ); this.i18nService = new BrowserI18nService(BrowserApi.getUILanguage(), this.stateService); this.cryptoService = new BrowserCryptoService( + this.keyGenerationService, this.cryptoFunctionService, this.encryptService, this.platformUtilsService, @@ -478,7 +482,7 @@ export default class MainBackground { this.tokenService, this.logService, this.organizationService, - this.cryptoFunctionService, + this.keyGenerationService, logoutCallback, ); @@ -506,6 +510,7 @@ export default class MainBackground { this.devicesApiService = new DevicesApiServiceImplementation(this.apiService); this.deviceTrustCryptoService = new DeviceTrustCryptoService( + this.keyGenerationService, this.cryptoFunctionService, this.cryptoService, this.encryptService, @@ -636,7 +641,7 @@ export default class MainBackground { this.sendService = new BrowserSendService( this.cryptoService, this.i18nService, - this.cryptoFunctionService, + this.keyGenerationService, this.stateService, ); this.sendApiService = new SendApiService( diff --git a/apps/browser/src/background/service-factories/send-service.factory.ts b/apps/browser/src/background/service-factories/send-service.factory.ts index bb5ef1fa37f..bca46b47030 100644 --- a/apps/browser/src/background/service-factories/send-service.factory.ts +++ b/apps/browser/src/background/service-factories/send-service.factory.ts @@ -1,6 +1,5 @@ import { InternalSendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; -import { cryptoFunctionServiceFactory } from "../../platform/background/service-factories/crypto-function-service.factory"; import { CryptoServiceInitOptions, cryptoServiceFactory, @@ -14,6 +13,10 @@ import { i18nServiceFactory, I18nServiceInitOptions, } from "../../platform/background/service-factories/i18n-service.factory"; +import { + KeyGenerationServiceInitOptions, + keyGenerationServiceFactory, +} from "../../platform/background/service-factories/key-generation-service.factory"; import { stateServiceFactory, StateServiceInitOptions, @@ -25,6 +28,7 @@ type SendServiceFactoryOptions = FactoryOptions; export type SendServiceInitOptions = SendServiceFactoryOptions & CryptoServiceInitOptions & I18nServiceInitOptions & + KeyGenerationServiceInitOptions & StateServiceInitOptions; export function sendServiceFactory( @@ -39,7 +43,7 @@ export function sendServiceFactory( new BrowserSendService( await cryptoServiceFactory(cache, opts), await i18nServiceFactory(cache, opts), - await cryptoFunctionServiceFactory(cache, opts), + await keyGenerationServiceFactory(cache, opts), await stateServiceFactory(cache, opts), ), ); diff --git a/apps/browser/src/platform/background/service-factories/crypto-service.factory.ts b/apps/browser/src/platform/background/service-factories/crypto-service.factory.ts index 1b09f4a9c37..765530beb6f 100644 --- a/apps/browser/src/platform/background/service-factories/crypto-service.factory.ts +++ b/apps/browser/src/platform/background/service-factories/crypto-service.factory.ts @@ -20,6 +20,10 @@ import { } from "./crypto-function-service.factory"; import { encryptServiceFactory, EncryptServiceInitOptions } from "./encrypt-service.factory"; import { FactoryOptions, CachedServices, factory } from "./factory-options"; +import { + KeyGenerationServiceInitOptions, + keyGenerationServiceFactory, +} from "./key-generation-service.factory"; import { PlatformUtilsServiceInitOptions, platformUtilsServiceFactory, @@ -29,6 +33,7 @@ import { StateProviderInitOptions, stateProviderFactory } from "./state-provider type CryptoServiceFactoryOptions = FactoryOptions; export type CryptoServiceInitOptions = CryptoServiceFactoryOptions & + KeyGenerationServiceInitOptions & CryptoFunctionServiceInitOptions & EncryptServiceInitOptions & PlatformUtilsServiceInitOptions & @@ -47,6 +52,7 @@ export function cryptoServiceFactory( opts, async () => new BrowserCryptoService( + await keyGenerationServiceFactory(cache, opts), await cryptoFunctionServiceFactory(cache, opts), await encryptServiceFactory(cache, opts), await platformUtilsServiceFactory(cache, opts), diff --git a/apps/browser/src/platform/background/service-factories/key-generation-service.factory.ts b/apps/browser/src/platform/background/service-factories/key-generation-service.factory.ts index d4f6d52738f..accba0023aa 100644 --- a/apps/browser/src/platform/background/service-factories/key-generation-service.factory.ts +++ b/apps/browser/src/platform/background/service-factories/key-generation-service.factory.ts @@ -1,4 +1,5 @@ -import { KeyGenerationService } from "../../services/key-generation.service"; +import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/services/key-generation.service"; import { cryptoFunctionServiceFactory, @@ -12,9 +13,9 @@ export type KeyGenerationServiceInitOptions = KeyGenerationServiceFactoryOptions CryptoFunctionServiceInitOptions; export function keyGenerationServiceFactory( - cache: { keyGenerationService?: KeyGenerationService } & CachedServices, + cache: { keyGenerationService?: KeyGenerationServiceAbstraction } & CachedServices, opts: KeyGenerationServiceInitOptions, -): Promise { +): Promise { return factory( cache, "keyGenerationService", diff --git a/apps/browser/src/platform/services/abstractions/abstract-key-generation.service.ts b/apps/browser/src/platform/services/abstractions/abstract-key-generation.service.ts deleted file mode 100644 index 5c2751dceff..00000000000 --- a/apps/browser/src/platform/services/abstractions/abstract-key-generation.service.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; - -export interface AbstractKeyGenerationService { - makeEphemeralKey(numBytes?: number): Promise; -} diff --git a/apps/browser/src/platform/services/key-generation.service.ts b/apps/browser/src/platform/services/key-generation.service.ts deleted file mode 100644 index 6b6f552c715..00000000000 --- a/apps/browser/src/platform/services/key-generation.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; -import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; - -import { AbstractKeyGenerationService } from "./abstractions/abstract-key-generation.service"; - -export class KeyGenerationService implements AbstractKeyGenerationService { - constructor(private cryptoFunctionService: CryptoFunctionService) {} - - async makeEphemeralKey(numBytes = 16): Promise { - const keyMaterial = await this.cryptoFunctionService.randomBytes(numBytes); - const key = await this.cryptoFunctionService.hkdf( - keyMaterial, - "bitwarden-ephemeral", - "ephemeral", - 64, - "sha256", - ); - return new SymmetricCryptoKey(key); - } -} diff --git a/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts b/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts index b6d6b99c014..fff9f2c28f3 100644 --- a/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts +++ b/apps/browser/src/platform/services/local-backed-session-storage.service.spec.ts @@ -1,13 +1,13 @@ import { mock, MockProxy } from "jest-mock-extended"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import BrowserLocalStorageService from "./browser-local-storage.service"; import BrowserMemoryStorageService from "./browser-memory-storage.service"; -import { KeyGenerationService } from "./key-generation.service"; import { LocalBackedSessionStorageService } from "./local-backed-session-storage.service"; describe("Browser Session Storage Service", () => { @@ -206,7 +206,11 @@ describe("Browser Session Storage Service", () => { describe("new key creation", () => { beforeEach(() => { jest.spyOn(sessionStorage, "get").mockResolvedValue(null); - keyGenerationService.makeEphemeralKey.mockResolvedValue(key); + keyGenerationService.createKeyWithPurpose.mockResolvedValue({ + salt: "salt", + material: null, + derivedKey: key, + }); jest.spyOn(sut, "setSessionEncKey").mockResolvedValue(); }); @@ -214,7 +218,7 @@ describe("Browser Session Storage Service", () => { const result = await sut.getSessionEncKey(); expect(result).toStrictEqual(key); - expect(keyGenerationService.makeEphemeralKey).toBeCalledTimes(1); + expect(keyGenerationService.createKeyWithPurpose).toBeCalledTimes(1); }); it("should store a symmetric crypto key if it makes one", async () => { diff --git a/apps/browser/src/platform/services/local-backed-session-storage.service.ts b/apps/browser/src/platform/services/local-backed-session-storage.service.ts index d17a338f7fb..b2823ffe4b4 100644 --- a/apps/browser/src/platform/services/local-backed-session-storage.service.ts +++ b/apps/browser/src/platform/services/local-backed-session-storage.service.ts @@ -2,6 +2,7 @@ import { Subject } from "rxjs"; import { Jsonify } from "type-fest"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { AbstractMemoryStorageService, StorageUpdate, @@ -13,7 +14,6 @@ import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/sym import { devFlag } from "../decorators/dev-flag.decorator"; import { devFlagEnabled } from "../flags"; -import { AbstractKeyGenerationService } from "./abstractions/abstract-key-generation.service"; import BrowserLocalStorageService from "./browser-local-storage.service"; import BrowserMemoryStorageService from "./browser-memory-storage.service"; @@ -31,7 +31,7 @@ export class LocalBackedSessionStorageService extends AbstractMemoryStorageServi constructor( private encryptService: EncryptService, - private keyGenerationService: AbstractKeyGenerationService, + private keyGenerationService: KeyGenerationService, ) { super(); this.updates$ = this.updatesSubject.asObservable(); @@ -138,10 +138,17 @@ export class LocalBackedSessionStorageService extends AbstractMemoryStorageServi async getSessionEncKey(): Promise { let storedKey = await this.sessionStorage.get(keys.encKey); if (storedKey == null || Object.keys(storedKey).length == 0) { - storedKey = await this.keyGenerationService.makeEphemeralKey(); + const generatedKey = await this.keyGenerationService.createKeyWithPurpose( + 128, + "ephemeral", + "bitwarden-ephemeral", + ); + storedKey = generatedKey.derivedKey; await this.setSessionEncKey(storedKey); + return storedKey; + } else { + return SymmetricCryptoKey.fromJSON(storedKey); } - return SymmetricCryptoKey.fromJSON(storedKey); } async setSessionEncKey(input: SymmetricCryptoKey): Promise { diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index c76e34e44df..55457d1c70f 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -53,6 +53,7 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { FileUploadService } from "@bitwarden/common/platform/abstractions/file-upload/file-upload.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService, LogService as LogServiceAbstraction, @@ -358,13 +359,13 @@ function getBgService(service: keyof MainBackground) { useFactory: ( cryptoService: CryptoService, i18nService: I18nServiceAbstraction, - cryptoFunctionService: CryptoFunctionService, + keyGenerationService: KeyGenerationService, stateServiceAbstraction: StateServiceAbstraction, ) => { return new BrowserSendService( cryptoService, i18nService, - cryptoFunctionService, + keyGenerationService, stateServiceAbstraction, ); }, diff --git a/apps/cli/src/bw.ts b/apps/cli/src/bw.ts index d1c46e9e0b2..e9acb7a5af5 100644 --- a/apps/cli/src/bw.ts +++ b/apps/cli/src/bw.ts @@ -38,6 +38,7 @@ import { UserVerificationService } from "@bitwarden/common/auth/services/user-ve import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; import { ClientType } from "@bitwarden/common/enums"; import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction"; +import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { KeySuffixOptions, LogLevelType } from "@bitwarden/common/platform/enums"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { Account } from "@bitwarden/common/platform/models/domain/account"; @@ -50,6 +51,7 @@ import { CryptoService } from "@bitwarden/common/platform/services/crypto.servic import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation"; import { EnvironmentService } from "@bitwarden/common/platform/services/environment.service"; import { FileUploadService } from "@bitwarden/common/platform/services/file-upload/file-upload.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/services/key-generation.service"; import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service"; import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service"; import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner"; @@ -164,6 +166,7 @@ export class Main { individualExportService: IndividualVaultExportServiceAbstraction; organizationExportService: OrganizationVaultExportServiceAbstraction; searchService: SearchService; + keyGenerationService: KeyGenerationServiceAbstraction; cryptoFunctionService: NodeCryptoFunctionService; encryptService: EncryptServiceImplementation; authService: AuthService; @@ -296,7 +299,10 @@ export class Main { migrationRunner, ); + this.keyGenerationService = new KeyGenerationService(this.cryptoFunctionService); + this.cryptoService = new CryptoService( + this.keyGenerationService, this.cryptoFunctionService, this.encryptService, this.platformUtilsService, @@ -337,7 +343,7 @@ export class Main { this.sendService = new SendService( this.cryptoService, this.i18nService, - this.cryptoFunctionService, + this.keyGenerationService, this.stateService, ); @@ -383,7 +389,7 @@ export class Main { this.tokenService, this.logService, this.organizationService, - this.cryptoFunctionService, + this.keyGenerationService, async (expired: boolean) => await this.logout(), ); @@ -399,6 +405,7 @@ export class Main { this.devicesApiService = new DevicesApiServiceImplementation(this.apiService); this.deviceTrustCryptoService = new DeviceTrustCryptoService( + this.keyGenerationService, this.cryptoFunctionService, this.cryptoService, this.encryptService, diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index d1dca936b57..06ac9e1deb9 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -25,6 +25,7 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt. import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService, LogService as LogServiceAbstraction, @@ -183,6 +184,7 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK"); provide: CryptoServiceAbstraction, useClass: ElectronCryptoService, deps: [ + KeyGenerationServiceAbstraction, CryptoFunctionServiceAbstraction, EncryptService, PlatformUtilsServiceAbstraction, diff --git a/apps/desktop/src/platform/services/electron-crypto.service.spec.ts b/apps/desktop/src/platform/services/electron-crypto.service.spec.ts index 8dbc9294f4b..58ea5c412ee 100644 --- a/apps/desktop/src/platform/services/electron-crypto.service.spec.ts +++ b/apps/desktop/src/platform/services/electron-crypto.service.spec.ts @@ -3,6 +3,7 @@ import { mock } from "jest-mock-extended"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; @@ -23,6 +24,7 @@ import { ElectronStateService } from "./electron-state.service.abstraction"; describe("electronCryptoService", () => { let sut: ElectronCryptoService; + const keyGenerationService = mock(); const cryptoFunctionService = mock(); const encryptService = mock(); const platformUtilService = mock(); @@ -39,6 +41,7 @@ describe("electronCryptoService", () => { stateProvider = new FakeStateProvider(accountService); sut = new ElectronCryptoService( + keyGenerationService, cryptoFunctionService, encryptService, platformUtilService, diff --git a/apps/desktop/src/platform/services/electron-crypto.service.ts b/apps/desktop/src/platform/services/electron-crypto.service.ts index ab9974c9551..184be5e1fb9 100644 --- a/apps/desktop/src/platform/services/electron-crypto.service.ts +++ b/apps/desktop/src/platform/services/electron-crypto.service.ts @@ -1,6 +1,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; @@ -18,6 +19,7 @@ import { ElectronStateService } from "./electron-state.service.abstraction"; export class ElectronCryptoService extends CryptoService { constructor( + keyGenerationService: KeyGenerationService, cryptoFunctionService: CryptoFunctionService, encryptService: EncryptService, platformUtilsService: PlatformUtilsService, @@ -28,6 +30,7 @@ export class ElectronCryptoService extends CryptoService { private biometricStateService: BiometricStateService, ) { super( + keyGenerationService, cryptoFunctionService, encryptService, platformUtilsService, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts index 93fb09307b6..c0e13961c08 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts @@ -3,9 +3,9 @@ import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; @@ -28,7 +28,7 @@ export class AccessService { constructor( private cryptoService: CryptoService, private apiService: ApiService, - private cryptoFunctionService: CryptoFunctionService, + private keyGenerationService: KeyGenerationService, private encryptService: EncryptService, ) {} @@ -53,19 +53,15 @@ export class AccessService { serviceAccountId: string, accessTokenView: AccessTokenView, ): Promise { - const keyMaterial = await this.cryptoFunctionService.aesGenerateKey(128); - const key = await this.cryptoFunctionService.hkdf( - keyMaterial, - "bitwarden-accesstoken", + const key = await this.keyGenerationService.createKeyWithPurpose( + 128, "sm-access-token", - 64, - "sha256", + "bitwarden-accesstoken", ); - const encryptionKey = new SymmetricCryptoKey(key); const request = await this.createAccessTokenRequest( organizationId, - encryptionKey, + key.derivedKey, accessTokenView, ); const r = await this.apiService.send( @@ -77,8 +73,8 @@ export class AccessService { ); const result = new AccessTokenCreationResponse(r); this._accessToken.next(null); - const b64Key = Utils.fromBufferToB64(keyMaterial); - return `${this._accessTokenVersion}.${result.id}.${result.clientSecret}:${b64Key}`; + const keyB64 = Utils.fromBufferToB64(key.material); + return `${this._accessTokenVersion}.${result.id}.${result.clientSecret}:${keyB64}`; } async revokeAccessTokens(serviceAccountId: string, accessTokenIds: string[]): Promise { diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index b833a3b929c..6f7716227d1 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -102,6 +102,7 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt. import { EnvironmentService as EnvironmentServiceAbstraction } from "@bitwarden/common/platform/abstractions/environment.service"; import { FileUploadService as FileUploadServiceAbstraction } from "@bitwarden/common/platform/abstractions/file-upload/file-upload.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -125,6 +126,7 @@ import { EncryptServiceImplementation } from "@bitwarden/common/platform/service import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation"; import { EnvironmentService } from "@bitwarden/common/platform/services/environment.service"; import { FileUploadService } from "@bitwarden/common/platform/services/file-upload/file-upload.service"; +import { KeyGenerationService } from "@bitwarden/common/platform/services/key-generation.service"; import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service"; import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner"; import { NoopNotificationsService } from "@bitwarden/common/platform/services/noop-notifications.service"; @@ -431,10 +433,16 @@ import { ModalService } from "./modal.service"; deps: [CryptoFunctionServiceAbstraction, LogService, StateServiceAbstraction], }, { provide: TokenServiceAbstraction, useClass: TokenService, deps: [StateServiceAbstraction] }, + { + provide: KeyGenerationServiceAbstraction, + useClass: KeyGenerationService, + deps: [CryptoFunctionServiceAbstraction], + }, { provide: CryptoServiceAbstraction, useClass: CryptoService, deps: [ + KeyGenerationServiceAbstraction, CryptoFunctionServiceAbstraction, EncryptService, PlatformUtilsServiceAbstraction, @@ -476,7 +484,7 @@ import { ModalService } from "./modal.service"; deps: [ CryptoServiceAbstraction, I18nServiceAbstraction, - CryptoFunctionServiceAbstraction, + KeyGenerationServiceAbstraction, StateServiceAbstraction, ], }, @@ -683,7 +691,7 @@ import { ModalService } from "./modal.service"; TokenServiceAbstraction, LogService, OrganizationServiceAbstraction, - CryptoFunctionServiceAbstraction, + KeyGenerationServiceAbstraction, LOGOUT_CALLBACK, ], }, @@ -825,6 +833,7 @@ import { ModalService } from "./modal.service"; provide: DeviceTrustCryptoServiceAbstraction, useClass: DeviceTrustCryptoService, deps: [ + KeyGenerationServiceAbstraction, CryptoFunctionServiceAbstraction, CryptoServiceAbstraction, EncryptService, diff --git a/libs/common/src/auth/services/device-trust-crypto.service.implementation.ts b/libs/common/src/auth/services/device-trust-crypto.service.implementation.ts index a5abac5e82e..9aa558ba537 100644 --- a/libs/common/src/auth/services/device-trust-crypto.service.implementation.ts +++ b/libs/common/src/auth/services/device-trust-crypto.service.implementation.ts @@ -5,11 +5,11 @@ import { CryptoFunctionService } from "../../platform/abstractions/crypto-functi import { CryptoService } from "../../platform/abstractions/crypto.service"; import { EncryptService } from "../../platform/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; +import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { PlatformUtilsService } from "../../platform/abstractions/platform-utils.service"; import { StateService } from "../../platform/abstractions/state.service"; import { EncString } from "../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; -import { CsprngArray } from "../../types/csprng"; import { UserKey, DeviceKey } from "../../types/key"; import { DeviceTrustCryptoServiceAbstraction } from "../abstractions/device-trust-crypto.service.abstraction"; import { DeviceResponse } from "../abstractions/devices/responses/device.response"; @@ -22,6 +22,7 @@ import { export class DeviceTrustCryptoService implements DeviceTrustCryptoServiceAbstraction { constructor( + private keyGenerationService: KeyGenerationService, private cryptoFunctionService: CryptoFunctionService, private cryptoService: CryptoService, private encryptService: EncryptService, @@ -165,10 +166,7 @@ export class DeviceTrustCryptoService implements DeviceTrustCryptoServiceAbstrac private async makeDeviceKey(): Promise { // Create 512-bit device key - const randomBytes: CsprngArray = await this.cryptoFunctionService.aesGenerateKey(512); - const deviceKey = new SymmetricCryptoKey(randomBytes) as DeviceKey; - - return deviceKey; + return (await this.keyGenerationService.createKey(512)) as DeviceKey; } async decryptUserKeyWithDeviceKey( diff --git a/libs/common/src/auth/services/device-trust-crypto.service.spec.ts b/libs/common/src/auth/services/device-trust-crypto.service.spec.ts index 0fbb954fb33..8c0a62b125e 100644 --- a/libs/common/src/auth/services/device-trust-crypto.service.spec.ts +++ b/libs/common/src/auth/services/device-trust-crypto.service.spec.ts @@ -7,6 +7,7 @@ import { CryptoFunctionService } from "../../platform/abstractions/crypto-functi import { CryptoService } from "../../platform/abstractions/crypto.service"; import { EncryptService } from "../../platform/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; +import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { PlatformUtilsService } from "../../platform/abstractions/platform-utils.service"; import { StateService } from "../../platform/abstractions/state.service"; import { EncryptionType } from "../../platform/enums/encryption-type.enum"; @@ -24,6 +25,7 @@ import { DeviceTrustCryptoService } from "./device-trust-crypto.service.implemen describe("deviceTrustCryptoService", () => { let deviceTrustCryptoService: DeviceTrustCryptoService; + const keyGenerationService = mock(); const cryptoFunctionService = mock(); const cryptoService = mock(); const encryptService = mock(); @@ -37,6 +39,7 @@ describe("deviceTrustCryptoService", () => { jest.clearAllMocks(); deviceTrustCryptoService = new DeviceTrustCryptoService( + keyGenerationService, cryptoFunctionService, cryptoService, encryptService, @@ -166,17 +169,18 @@ describe("deviceTrustCryptoService", () => { describe("makeDeviceKey", () => { it("creates a new non-null 64 byte device key, securely stores it, and returns it", async () => { const mockRandomBytes = new Uint8Array(deviceKeyBytesLength) as CsprngArray; + const mockDeviceKey = new SymmetricCryptoKey(mockRandomBytes) as DeviceKey; - const cryptoFuncSvcGenerateKeySpy = jest - .spyOn(cryptoFunctionService, "aesGenerateKey") - .mockResolvedValue(mockRandomBytes); + const keyGenSvcGenerateKeySpy = jest + .spyOn(keyGenerationService, "createKey") + .mockResolvedValue(mockDeviceKey); // 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 (deviceTrustCryptoService as any).makeDeviceKey(); - expect(cryptoFuncSvcGenerateKeySpy).toHaveBeenCalledTimes(1); - expect(cryptoFuncSvcGenerateKeySpy).toHaveBeenCalledWith(deviceKeyBytesLength * 8); + expect(keyGenSvcGenerateKeySpy).toHaveBeenCalledTimes(1); + expect(keyGenSvcGenerateKeySpy).toHaveBeenCalledWith(deviceKeyBytesLength * 8); expect(deviceKey).not.toBeNull(); expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey); diff --git a/libs/common/src/auth/services/key-connector.service.ts b/libs/common/src/auth/services/key-connector.service.ts index 654caca845c..cded13a74bf 100644 --- a/libs/common/src/auth/services/key-connector.service.ts +++ b/libs/common/src/auth/services/key-connector.service.ts @@ -2,8 +2,8 @@ import { ApiService } from "../../abstractions/api.service"; import { OrganizationService } from "../../admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationUserType } from "../../admin-console/enums"; import { KeysRequest } from "../../models/request/keys.request"; -import { CryptoFunctionService } from "../../platform/abstractions/crypto-function.service"; import { CryptoService } from "../../platform/abstractions/crypto.service"; +import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { LogService } from "../../platform/abstractions/log.service"; import { StateService } from "../../platform/abstractions/state.service"; import { Utils } from "../../platform/misc/utils"; @@ -24,7 +24,7 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction { private tokenService: TokenService, private logService: LogService, private organizationService: OrganizationService, - private cryptoFunctionService: CryptoFunctionService, + private keyGenerationService: KeyGenerationService, private logoutCallback: (expired: boolean, userId?: string) => Promise, ) {} @@ -94,11 +94,11 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction { keyConnectorUrl: legacyKeyConnectorUrl, userDecryptionOptions, } = tokenResponse; - const password = await this.cryptoFunctionService.aesGenerateKey(512); + const password = await this.keyGenerationService.createKey(512); const kdfConfig = new KdfConfig(kdfIterations, kdfMemory, kdfParallelism); const masterKey = await this.cryptoService.makeMasterKey( - Utils.fromBufferToB64(password), + password.keyB64, await this.tokenService.getEmail(), kdf, kdfConfig, diff --git a/libs/common/src/platform/abstractions/key-generation.service.ts b/libs/common/src/platform/abstractions/key-generation.service.ts new file mode 100644 index 00000000000..a015182f89f --- /dev/null +++ b/libs/common/src/platform/abstractions/key-generation.service.ts @@ -0,0 +1,59 @@ +import { KdfConfig } from "../../auth/models/domain/kdf-config"; +import { CsprngArray } from "../../types/csprng"; +import { KdfType } from "../enums"; +import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; + +export abstract class KeyGenerationService { + /** + * Generates a key of the given length suitable for use in AES encryption + * @param bitLength Length of key. + * 256 bits = 32 bytes + * 512 bits = 64 bytes + * @returns Generated key. + */ + createKey: (bitLength: 256 | 512) => Promise; + /** + * Generates key material from CSPRNG and derives a 64 byte key from it. + * Uses HKDF, see {@link https://datatracker.ietf.org/doc/html/rfc5869 RFC 5869} + * for details. + * @param bitLength Length of key material. + * @param purpose Purpose for the key derivation function. + * Different purposes results in different keys, even with the same material. + * @param salt Optional. If not provided will be generated from CSPRNG. + * @returns An object containing the salt, key material, and derived key. + */ + createKeyWithPurpose: ( + bitLength: 128 | 192 | 256 | 512, + purpose: string, + salt?: string, + ) => Promise<{ salt: string; material: CsprngArray; derivedKey: SymmetricCryptoKey }>; + /** + * Derives a 64 byte key from key material. + * @remark The key material should be generated from {@link createKey}, or {@link createKeyWithPurpose}. + * Uses HKDF, see {@link https://datatracker.ietf.org/doc/html/rfc5869 RFC 5869} for details. + * @param material key material. + * @param salt Salt for the key derivation function. + * @param purpose Purpose for the key derivation function. + * Different purposes results in different keys, even with the same material. + * @returns 64 byte derived key. + */ + deriveKeyFromMaterial: ( + material: CsprngArray, + salt: string, + purpose: string, + ) => Promise; + /** + * Derives a 32 byte key from a password using a key derivation function. + * @param password Password to derive the key from. + * @param salt Salt for the key derivation function. + * @param kdf Key derivation function to use. + * @param kdfConfig Configuration for the key derivation function. + * @returns 32 byte derived key. + */ + deriveKeyFromPassword: ( + password: string | Uint8Array, + salt: string | Uint8Array, + kdf: KdfType, + kdfConfig: KdfConfig, + ) => Promise; +} diff --git a/libs/common/src/platform/services/crypto.service.spec.ts b/libs/common/src/platform/services/crypto.service.spec.ts index fd4e5b92c76..a8fa48f36f2 100644 --- a/libs/common/src/platform/services/crypto.service.spec.ts +++ b/libs/common/src/platform/services/crypto.service.spec.ts @@ -10,6 +10,7 @@ import { UserId } from "../../types/guid"; import { UserKey, MasterKey, PinKey } from "../../types/key"; import { CryptoFunctionService } from "../abstractions/crypto-function.service"; import { EncryptService } from "../abstractions/encrypt.service"; +import { KeyGenerationService } from "../abstractions/key-generation.service"; import { LogService } from "../abstractions/log.service"; import { PlatformUtilsService } from "../abstractions/platform-utils.service"; import { StateService } from "../abstractions/state.service"; @@ -23,6 +24,7 @@ import { USER_EVER_HAD_USER_KEY, USER_KEY } from "./key-state/user-key.state"; describe("cryptoService", () => { let cryptoService: CryptoService; + const keyGenerationService = mock(); const cryptoFunctionService = mock(); const encryptService = mock(); const platformUtilService = mock(); @@ -38,6 +40,7 @@ describe("cryptoService", () => { stateProvider = new FakeStateProvider(accountService); cryptoService = new CryptoService( + keyGenerationService, cryptoFunctionService, encryptService, platformUtilService, diff --git a/libs/common/src/platform/services/crypto.service.ts b/libs/common/src/platform/services/crypto.service.ts index 83faf4f7d37..82dd7ce5c23 100644 --- a/libs/common/src/platform/services/crypto.service.ts +++ b/libs/common/src/platform/services/crypto.service.ts @@ -9,6 +9,7 @@ import { AccountService } from "../../auth/abstractions/account.service"; import { AuthenticationStatus } from "../../auth/enums/authentication-status"; import { KdfConfig } from "../../auth/models/domain/kdf-config"; import { Utils } from "../../platform/misc/utils"; +import { CsprngArray } from "../../types/csprng"; import { OrganizationId, ProviderId, UserId } from "../../types/guid"; import { OrgKey, @@ -23,6 +24,7 @@ import { import { CryptoFunctionService } from "../abstractions/crypto-function.service"; import { CryptoService as CryptoServiceAbstraction } from "../abstractions/crypto.service"; import { EncryptService } from "../abstractions/encrypt.service"; +import { KeyGenerationService } from "../abstractions/key-generation.service"; import { LogService } from "../abstractions/log.service"; import { PlatformUtilsService } from "../abstractions/platform-utils.service"; import { StateService } from "../abstractions/state.service"; @@ -80,6 +82,7 @@ export class CryptoService implements CryptoServiceAbstraction { readonly everHadUserKey$: Observable; constructor( + protected keyGenerationService: KeyGenerationService, protected cryptoFunctionService: CryptoFunctionService, protected encryptService: EncryptService, protected platformUtilService: PlatformUtilsService, @@ -219,8 +222,8 @@ export class CryptoService implements CryptoServiceAbstraction { throw new Error("No Master Key found."); } - const newUserKey = await this.cryptoFunctionService.aesGenerateKey(512); - return this.buildProtectedSymmetricKey(masterKey, newUserKey); + const newUserKey = await this.keyGenerationService.createKey(512); + return this.buildProtectedSymmetricKey(masterKey, newUserKey.key); } async clearUserKey(clearStoredKeys = true, userId?: UserId): Promise { @@ -294,7 +297,12 @@ export class CryptoService implements CryptoServiceAbstraction { kdf: KdfType, KdfConfig: KdfConfig, ): Promise { - return (await this.makeKey(password, email, kdf, KdfConfig)) as MasterKey; + return (await this.keyGenerationService.deriveKeyFromPassword( + password, + email, + kdf, + KdfConfig, + )) as MasterKey; } async clearMasterKey(userId?: UserId): Promise { @@ -452,8 +460,8 @@ export class CryptoService implements CryptoServiceAbstraction { throw new Error("No key provided"); } - const newSymKey = await this.cryptoFunctionService.aesGenerateKey(512); - return this.buildProtectedSymmetricKey(key, newSymKey); + const newSymKey = await this.keyGenerationService.createKey(512); + return this.buildProtectedSymmetricKey(key, newSymKey.key); } async clearOrgKeys(memoryOnly?: boolean, userId?: UserId): Promise { @@ -522,10 +530,10 @@ export class CryptoService implements CryptoServiceAbstraction { } async makeOrgKey(): Promise<[EncString, T]> { - const shareKey = await this.cryptoFunctionService.aesGenerateKey(512); + const shareKey = await this.keyGenerationService.createKey(512); const publicKey = await this.getPublicKey(); - const encShareKey = await this.rsaEncrypt(shareKey, publicKey); - return [encShareKey, new SymmetricCryptoKey(shareKey) as T]; + const encShareKey = await this.rsaEncrypt(shareKey.key, publicKey); + return [encShareKey, shareKey as T]; } async setPrivateKey(encPrivateKey: EncryptedString): Promise { @@ -588,7 +596,7 @@ export class CryptoService implements CryptoServiceAbstraction { } async makePinKey(pin: string, salt: string, kdf: KdfType, kdfConfig: KdfConfig): Promise { - const pinKey = await this.makeKey(pin, salt, kdf, kdfConfig); + const pinKey = await this.keyGenerationService.deriveKeyFromPassword(pin, salt, kdf, kdfConfig); return (await this.stretchKey(pinKey)) as PinKey; } @@ -636,20 +644,16 @@ export class CryptoService implements CryptoServiceAbstraction { return new SymmetricCryptoKey(masterKey) as MasterKey; } - async makeSendKey(keyMaterial: Uint8Array): Promise { - const sendKey = await this.cryptoFunctionService.hkdf( + async makeSendKey(keyMaterial: CsprngArray): Promise { + return await this.keyGenerationService.deriveKeyFromMaterial( keyMaterial, "bitwarden-send", "send", - 64, - "sha256", ); - return new SymmetricCryptoKey(sendKey); } async makeCipherKey(): Promise { - const randomBytes = await this.cryptoFunctionService.aesGenerateKey(512); - return new SymmetricCryptoKey(randomBytes) as CipherKey; + return (await this.keyGenerationService.createKey(512)) as CipherKey; } async clearKeys(userId?: UserId): Promise { @@ -802,8 +806,7 @@ export class CryptoService implements CryptoServiceAbstraction { publicKey: string; privateKey: EncString; }> { - const rawKey = await this.cryptoFunctionService.aesGenerateKey(512); - const userKey = new SymmetricCryptoKey(rawKey) as UserKey; + const userKey = (await this.keyGenerationService.createKey(512)) as UserKey; const [publicKey, privateKey] = await this.makeKeyPair(userKey); await this.setUserKey(userKey); await this.activeUserEncryptedPrivateKeyState.update(() => privateKey.encryptedString); @@ -986,46 +989,6 @@ export class CryptoService implements CryptoServiceAbstraction { return [new SymmetricCryptoKey(newSymKey) as T, protectedSymKey]; } - private async makeKey( - password: string, - salt: string, - kdf: KdfType, - kdfConfig: KdfConfig, - ): Promise { - let key: Uint8Array = null; - if (kdf == null || kdf === KdfType.PBKDF2_SHA256) { - if (kdfConfig.iterations == null) { - kdfConfig.iterations = PBKDF2_ITERATIONS.defaultValue; - } - - key = await this.cryptoFunctionService.pbkdf2(password, salt, "sha256", kdfConfig.iterations); - } else if (kdf == KdfType.Argon2id) { - if (kdfConfig.iterations == null) { - kdfConfig.iterations = ARGON2_ITERATIONS.defaultValue; - } - - if (kdfConfig.memory == null) { - kdfConfig.memory = ARGON2_MEMORY.defaultValue; - } - - if (kdfConfig.parallelism == null) { - kdfConfig.parallelism = ARGON2_PARALLELISM.defaultValue; - } - - const saltHash = await this.cryptoFunctionService.hash(salt, "sha256"); - key = await this.cryptoFunctionService.argon2( - password, - saltHash, - kdfConfig.iterations, - kdfConfig.memory * 1024, // convert to KiB from MiB - kdfConfig.parallelism, - ); - } else { - throw new Error("Unknown Kdf."); - } - return new SymmetricCryptoKey(key); - } - // --LEGACY METHODS-- // We previously used the master key for additional keys, but now we use the user key. // These methods support migrating the old keys to the new ones. diff --git a/libs/common/src/platform/services/key-generation.service.spec.ts b/libs/common/src/platform/services/key-generation.service.spec.ts new file mode 100644 index 00000000000..b3e0aa6d4e1 --- /dev/null +++ b/libs/common/src/platform/services/key-generation.service.spec.ts @@ -0,0 +1,102 @@ +import { mock } from "jest-mock-extended"; + +import { KdfConfig } from "../../auth/models/domain/kdf-config"; +import { CsprngArray } from "../../types/csprng"; +import { CryptoFunctionService } from "../abstractions/crypto-function.service"; +import { KdfType } from "../enums"; + +import { KeyGenerationService } from "./key-generation.service"; + +describe("KeyGenerationService", () => { + let sut: KeyGenerationService; + + const cryptoFunctionService = mock(); + + beforeEach(() => { + sut = new KeyGenerationService(cryptoFunctionService); + }); + + describe("createKey", () => { + test.each([256, 512])( + "it should delegate key creation to crypto function service", + async (bitLength: 256 | 512) => { + cryptoFunctionService.aesGenerateKey + .calledWith(bitLength) + .mockResolvedValue(new Uint8Array(bitLength / 8) as CsprngArray); + + await sut.createKey(bitLength); + + expect(cryptoFunctionService.aesGenerateKey).toHaveBeenCalledWith(bitLength); + }, + ); + }); + + describe("createMaterialAndKey", () => { + test.each([128, 192, 256, 512])( + "should create a 64 byte key from different material lengths", + async (bitLength: 128 | 192 | 256 | 512) => { + const inputMaterial = new Uint8Array(bitLength / 8) as CsprngArray; + const inputSalt = "salt"; + const purpose = "purpose"; + + cryptoFunctionService.aesGenerateKey.calledWith(bitLength).mockResolvedValue(inputMaterial); + cryptoFunctionService.hkdf + .calledWith(inputMaterial, inputSalt, purpose, 64, "sha256") + .mockResolvedValue(new Uint8Array(64)); + + const { salt, material, derivedKey } = await sut.createKeyWithPurpose( + bitLength, + purpose, + inputSalt, + ); + + expect(salt).toEqual(inputSalt); + expect(material).toEqual(inputMaterial); + expect(derivedKey.key.length).toEqual(64); + }, + ); + }); + + describe("deriveKeyFromMaterial", () => { + it("should derive a 64 byte key from material", async () => { + const material = new Uint8Array(32) as CsprngArray; + const salt = "salt"; + const purpose = "purpose"; + + cryptoFunctionService.hkdf.mockResolvedValue(new Uint8Array(64)); + + const key = await sut.deriveKeyFromMaterial(material, salt, purpose); + + expect(key.key.length).toEqual(64); + }); + }); + + describe("deriveKeyFromPassword", () => { + it("should derive a 32 byte key from a password using pbkdf2", async () => { + const password = "password"; + const salt = "salt"; + const kdf = KdfType.PBKDF2_SHA256; + const kdfConfig = new KdfConfig(600_000); + + cryptoFunctionService.pbkdf2.mockResolvedValue(new Uint8Array(32)); + + const key = await sut.deriveKeyFromPassword(password, salt, kdf, kdfConfig); + + expect(key.key.length).toEqual(32); + }); + + it("should derive a 32 byte key from a password using argon2id", async () => { + const password = "password"; + const salt = "salt"; + const kdf = KdfType.Argon2id; + const kdfConfig = new KdfConfig(600_000, 15); + + cryptoFunctionService.hash.mockResolvedValue(new Uint8Array(32)); + cryptoFunctionService.argon2.mockResolvedValue(new Uint8Array(32)); + + const key = await sut.deriveKeyFromPassword(password, salt, kdf, kdfConfig); + + expect(key.key.length).toEqual(32); + }); + }); +}); diff --git a/libs/common/src/platform/services/key-generation.service.ts b/libs/common/src/platform/services/key-generation.service.ts new file mode 100644 index 00000000000..c592f35e5f0 --- /dev/null +++ b/libs/common/src/platform/services/key-generation.service.ts @@ -0,0 +1,85 @@ +import { KdfConfig } from "../../auth/models/domain/kdf-config"; +import { CsprngArray } from "../../types/csprng"; +import { CryptoFunctionService } from "../abstractions/crypto-function.service"; +import { KeyGenerationService as KeyGenerationServiceAbstraction } from "../abstractions/key-generation.service"; +import { + ARGON2_ITERATIONS, + ARGON2_MEMORY, + ARGON2_PARALLELISM, + KdfType, + PBKDF2_ITERATIONS, +} from "../enums"; +import { Utils } from "../misc/utils"; +import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; + +export class KeyGenerationService implements KeyGenerationServiceAbstraction { + constructor(private cryptoFunctionService: CryptoFunctionService) {} + + async createKey(bitLength: 256 | 512): Promise { + const key = await this.cryptoFunctionService.aesGenerateKey(bitLength); + return new SymmetricCryptoKey(key); + } + + async createKeyWithPurpose( + bitLength: 128 | 192 | 256 | 512, + purpose: string, + salt?: string, + ): Promise<{ salt: string; material: CsprngArray; derivedKey: SymmetricCryptoKey }> { + if (salt == null) { + const bytes = await this.cryptoFunctionService.randomBytes(32); + salt = Utils.fromBufferToUtf8(bytes); + } + const material = await this.cryptoFunctionService.aesGenerateKey(bitLength); + const key = await this.cryptoFunctionService.hkdf(material, salt, purpose, 64, "sha256"); + return { salt, material, derivedKey: new SymmetricCryptoKey(key) }; + } + + async deriveKeyFromMaterial( + material: CsprngArray, + salt: string, + purpose: string, + ): Promise { + const key = await this.cryptoFunctionService.hkdf(material, salt, purpose, 64, "sha256"); + return new SymmetricCryptoKey(key); + } + + async deriveKeyFromPassword( + password: string | Uint8Array, + salt: string | Uint8Array, + kdf: KdfType, + kdfConfig: KdfConfig, + ): Promise { + let key: Uint8Array = null; + if (kdf == null || kdf === KdfType.PBKDF2_SHA256) { + if (kdfConfig.iterations == null) { + kdfConfig.iterations = PBKDF2_ITERATIONS.defaultValue; + } + + key = await this.cryptoFunctionService.pbkdf2(password, salt, "sha256", kdfConfig.iterations); + } else if (kdf == KdfType.Argon2id) { + if (kdfConfig.iterations == null) { + kdfConfig.iterations = ARGON2_ITERATIONS.defaultValue; + } + + if (kdfConfig.memory == null) { + kdfConfig.memory = ARGON2_MEMORY.defaultValue; + } + + if (kdfConfig.parallelism == null) { + kdfConfig.parallelism = ARGON2_PARALLELISM.defaultValue; + } + + const saltHash = await this.cryptoFunctionService.hash(salt, "sha256"); + key = await this.cryptoFunctionService.argon2( + password, + saltHash, + kdfConfig.iterations, + kdfConfig.memory * 1024, // convert to KiB from MiB + kdfConfig.parallelism, + ); + } else { + throw new Error("Unknown Kdf."); + } + return new SymmetricCryptoKey(key); + } +} diff --git a/libs/common/src/tools/send/services/send.service.spec.ts b/libs/common/src/tools/send/services/send.service.spec.ts index 65bc5b5e353..568bd70d525 100644 --- a/libs/common/src/tools/send/services/send.service.spec.ts +++ b/libs/common/src/tools/send/services/send.service.spec.ts @@ -1,10 +1,10 @@ import { any, mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom } from "rxjs"; -import { CryptoFunctionService } from "../../../platform/abstractions/crypto-function.service"; import { CryptoService } from "../../../platform/abstractions/crypto.service"; import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; +import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; import { StateService } from "../../../platform/abstractions/state.service"; import { EncString } from "../../../platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -24,7 +24,7 @@ import { SendService } from "./send.service"; describe("SendService", () => { const cryptoService = mock(); const i18nService = mock(); - const cryptoFunctionService = mock(); + const keyGenerationService = mock(); const encryptService = mock(); let sendService: SendService; @@ -50,7 +50,7 @@ describe("SendService", () => { .calledWith(any()) .mockResolvedValue([sendView("1", "Test Send")]); - sendService = new SendService(cryptoService, i18nService, cryptoFunctionService, stateService); + sendService = new SendService(cryptoService, i18nService, keyGenerationService, stateService); }); afterEach(() => { diff --git a/libs/common/src/tools/send/services/send.service.ts b/libs/common/src/tools/send/services/send.service.ts index 0002cad3797..528f90c1dc1 100644 --- a/libs/common/src/tools/send/services/send.service.ts +++ b/libs/common/src/tools/send/services/send.service.ts @@ -1,9 +1,10 @@ import { BehaviorSubject, Observable, concatMap, distinctUntilChanged, map } from "rxjs"; -import { CryptoFunctionService } from "../../../platform/abstractions/crypto-function.service"; import { CryptoService } from "../../../platform/abstractions/crypto.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; +import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; import { StateService } from "../../../platform/abstractions/state.service"; +import { KdfType } from "../../../platform/enums"; import { Utils } from "../../../platform/misc/utils"; import { EncArrayBuffer } from "../../../platform/models/domain/enc-array-buffer"; import { EncString } from "../../../platform/models/domain/enc-string"; @@ -21,6 +22,9 @@ import { SEND_KDF_ITERATIONS } from "../send-kdf"; import { InternalSendService as InternalSendServiceAbstraction } from "./send.service.abstraction"; export class SendService implements InternalSendServiceAbstraction { + readonly sendKeySalt = "bitwarden-send"; + readonly sendKeyPurpose = "send"; + protected _sends: BehaviorSubject = new BehaviorSubject([]); protected _sendViews: BehaviorSubject = new BehaviorSubject([]); @@ -30,7 +34,7 @@ export class SendService implements InternalSendServiceAbstraction { constructor( private cryptoService: CryptoService, private i18nService: I18nService, - private cryptoFunctionService: CryptoFunctionService, + private keyGenerationService: KeyGenerationService, private stateService: StateService, ) { this.stateService.activeAccountUnlocked$ @@ -72,17 +76,22 @@ export class SendService implements InternalSendServiceAbstraction { send.hideEmail = model.hideEmail; send.maxAccessCount = model.maxAccessCount; if (model.key == null) { - model.key = await this.cryptoFunctionService.aesGenerateKey(128); - model.cryptoKey = await this.cryptoService.makeSendKey(model.key); + const key = await this.keyGenerationService.createKeyWithPurpose( + 128, + this.sendKeyPurpose, + this.sendKeySalt, + ); + model.key = key.material; + model.cryptoKey = key.derivedKey; } if (password != null) { - const passwordHash = await this.cryptoFunctionService.pbkdf2( + const passwordKey = await this.keyGenerationService.deriveKeyFromPassword( password, model.key, - "sha256", - SEND_KDF_ITERATIONS, + KdfType.PBKDF2_SHA256, + { iterations: SEND_KDF_ITERATIONS }, ); - send.password = Utils.fromBufferToB64(passwordHash); + send.password = passwordKey.keyB64; } send.key = await this.cryptoService.encrypt(model.key, key); send.name = await this.cryptoService.encrypt(model.name, model.cryptoKey); From 9775e77079896d9b1e4e8242d8e0090f86e52600 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Fri, 23 Feb 2024 09:21:18 -0500 Subject: [PATCH 007/124] [PM-5537] Migrate Biometric Prompts (#7771) * Fix nextMock arguments * Add state for biometric prompts * Use biometric state for prompts * Migrate biometric prompt data * wire up biometric state to logouts * Add migrator to migrate list * Remove usages of prompt automatically Explicitly list non-nulled state as intentional * `npm run prettier` :robot: * Fix web lock component --- apps/browser/src/auth/popup/lock.component.ts | 9 +- .../browser/src/background/main.background.ts | 15 +- .../src/popup/settings/settings.component.ts | 10 +- apps/cli/src/bw.ts | 3 + .../src/app/accounts/settings.component.ts | 17 ++- apps/desktop/src/app/app.component.ts | 3 + .../src/app/services/services.module.ts | 5 - apps/desktop/src/auth/lock.component.spec.ts | 37 ++--- apps/desktop/src/auth/lock.component.ts | 22 +-- apps/desktop/src/main.ts | 8 +- apps/desktop/src/main/window.main.ts | 8 +- .../main/biometric/biometrics.service.spec.ts | 4 +- .../main/biometric/biometrics.service.ts | 4 +- .../services/electron-crypto.service.spec.ts | 4 +- .../services/electron-crypto.service.ts | 5 +- .../electron-state.service.abstraction.ts | 9 -- .../services/electron-state.service.ts | 25 +--- .../encrypted-message-handler.service.ts | 4 +- apps/web/src/app/app.component.ts | 4 + apps/web/src/app/auth/lock.component.ts | 3 + .../src/auth/components/lock.component.ts | 6 +- libs/common/spec/fake-state.ts | 3 + .../platform/abstractions/state.service.ts | 14 -- .../biometric-state.service.spec.ts | 60 +++++++- .../biometrics/biometric-state.service.ts | 81 ++++++++++- .../biometrics/biometric.state.spec.ts | 57 +++++--- .../platform/biometrics/biometric.state.ts | 35 +++++ .../src/platform/models/domain/account.ts | 2 - .../src/platform/services/state.service.ts | 36 ----- libs/common/src/state-migrations/migrate.ts | 6 +- ...ometric-prompts-to-state-providers.spec.ts | 131 ++++++++++++++++++ ...ve-biometric-prompts-to-state-providers.ts | 99 +++++++++++++ 32 files changed, 549 insertions(+), 180 deletions(-) delete mode 100644 apps/desktop/src/platform/services/electron-state.service.abstraction.ts create mode 100644 libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.spec.ts create mode 100644 libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.ts diff --git a/apps/browser/src/auth/popup/lock.component.ts b/apps/browser/src/auth/popup/lock.component.ts index 42c2d44e31b..7aa5a96b4ea 100644 --- a/apps/browser/src/auth/popup/lock.component.ts +++ b/apps/browser/src/auth/popup/lock.component.ts @@ -1,5 +1,6 @@ import { Component, NgZone } from "@angular/core"; import { Router } from "@angular/router"; +import { firstValueFrom } from "rxjs"; import { LockComponent as BaseLockComponent } from "@bitwarden/angular/auth/components/lock.component"; import { PinCryptoServiceAbstraction } from "@bitwarden/auth/common"; @@ -19,6 +20,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { DialogService } from "@bitwarden/components"; @@ -59,6 +61,7 @@ export class LockComponent extends BaseLockComponent { userVerificationService: UserVerificationService, pinCryptoService: PinCryptoServiceAbstraction, private routerService: BrowserRouterService, + biometricStateService: BiometricStateService, ) { super( router, @@ -80,6 +83,7 @@ export class LockComponent extends BaseLockComponent { deviceTrustCryptoService, userVerificationService, pinCryptoService, + biometricStateService, ); this.successRoute = "/tabs/current"; this.isInitialLockScreen = (window as any).previousPopupUrl == null; @@ -100,8 +104,9 @@ export class LockComponent extends BaseLockComponent { async ngOnInit() { await super.ngOnInit(); - const disableAutoBiometricsPrompt = - (await this.stateService.getDisableAutoBiometricsPrompt()) ?? true; + const disableAutoBiometricsPrompt = await firstValueFrom( + this.biometricStateService.promptAutomatically$, + ); window.setTimeout(async () => { document.getElementById(this.pinEnabled ? "pin" : "masterPassword")?.focus(); diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 3df24d40fe1..d742e2ebe6b 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -1,3 +1,5 @@ +import { firstValueFrom } from "rxjs"; + import { PinCryptoServiceAbstraction, PinCryptoService, @@ -64,6 +66,10 @@ import { ObservableStorageService, } from "@bitwarden/common/platform/abstractions/storage.service"; import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/platform/abstractions/system.service"; +import { + BiometricStateService, + DefaultBiometricStateService, +} from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state"; import { AppIdService } from "@bitwarden/common/platform/services/app-id.service"; @@ -280,6 +286,7 @@ export default class MainBackground { individualVaultExportService: IndividualVaultExportServiceAbstraction; organizationVaultExportService: OrganizationVaultExportServiceAbstraction; vaultSettingsService: VaultSettingsServiceAbstraction; + biometricStateService: BiometricStateService; // Passed to the popup for Safari to workaround issues with theming, downloading, etc. backgroundWindow = window; @@ -321,7 +328,7 @@ export default class MainBackground { } }; - const logoutCallback = async (expired: boolean, userId?: string) => + const logoutCallback = async (expired: boolean, userId?: UserId) => await this.logout(expired, userId); this.messagingService = this.popupOnlyContext @@ -386,6 +393,7 @@ export default class MainBackground { this.stateProvider, this.accountService, ); + this.biometricStateService = new DefaultBiometricStateService(this.stateProvider); const migrationRunner = new MigrationRunner( this.storageService, @@ -1043,7 +1051,9 @@ export default class MainBackground { } } - async logout(expired: boolean, userId?: string) { + async logout(expired: boolean, userId?: UserId) { + userId ??= (await firstValueFrom(this.accountService.activeAccount$))?.id; + await this.eventUploadService.uploadEvents(userId); await Promise.all([ @@ -1058,6 +1068,7 @@ export default class MainBackground { this.vaultTimeoutSettingsService.clear(userId), this.keyConnectorService.clear(), this.vaultFilterService.clear(), + this.biometricStateService.logout(userId), // We intentionally do not clear the autofillSettingsService ]); diff --git a/apps/browser/src/popup/settings/settings.component.ts b/apps/browser/src/popup/settings/settings.component.ts index 703d2802a39..1914d2583a2 100644 --- a/apps/browser/src/popup/settings/settings.component.ts +++ b/apps/browser/src/popup/settings/settings.component.ts @@ -31,6 +31,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { DialogService } from "@bitwarden/components"; import { SetPinComponent } from "../../auth/popup/components/set-pin.component"; @@ -101,6 +102,7 @@ export class SettingsComponent implements OnInit { private userVerificationService: UserVerificationService, private dialogService: DialogService, private changeDetectorRef: ChangeDetectorRef, + private biometricStateService: BiometricStateService, ) { this.accountSwitcherEnabled = enableAccountSwitching(); } @@ -176,7 +178,9 @@ export class SettingsComponent implements OnInit { ), pin: pinStatus !== "DISABLED", biometric: await this.vaultTimeoutSettingsService.isBiometricLockSet(), - enableAutoBiometricsPrompt: !(await this.stateService.getDisableAutoBiometricsPrompt()), + enableAutoBiometricsPrompt: await firstValueFrom( + this.biometricStateService.promptAutomatically$, + ), }; this.form.patchValue(initialValues); // Emit event to initialize `pairwise` operator @@ -416,8 +420,8 @@ export class SettingsComponent implements OnInit { } async updateAutoBiometricsPrompt() { - await this.stateService.setDisableAutoBiometricsPrompt( - !this.form.value.enableAutoBiometricsPrompt, + await this.biometricStateService.setPromptAutomatically( + this.form.value.enableAutoBiometricsPrompt, ); } diff --git a/apps/cli/src/bw.ts b/apps/cli/src/bw.ts index e9acb7a5af5..fb24d982926 100644 --- a/apps/cli/src/bw.ts +++ b/apps/cli/src/bw.ts @@ -39,6 +39,7 @@ import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/s import { ClientType } from "@bitwarden/common/enums"; import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction"; import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { KeySuffixOptions, LogLevelType } from "@bitwarden/common/platform/enums"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { Account } from "@bitwarden/common/platform/models/domain/account"; @@ -205,6 +206,7 @@ export class Main { derivedStateProvider: DerivedStateProvider; stateProvider: StateProvider; loginStrategyService: LoginStrategyServiceAbstraction; + biometricStateService: BiometricStateService; constructor() { let p = null; @@ -627,6 +629,7 @@ export class Main { this.collectionService.clear(userId as UserId), this.policyService.clear(userId), this.passwordGenerationService.clear(), + this.biometricStateService.logout(userId as UserId), ]); await this.stateService.clean(); process.env.BW_SESSION = null; diff --git a/apps/desktop/src/app/accounts/settings.component.ts b/apps/desktop/src/app/accounts/settings.component.ts index 10b7d20d385..4c5c2060f84 100644 --- a/apps/desktop/src/app/accounts/settings.component.ts +++ b/apps/desktop/src/app/accounts/settings.component.ts @@ -16,6 +16,7 @@ import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.se import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { ThemeType, KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -23,7 +24,6 @@ import { DialogService } from "@bitwarden/components"; import { SetPinComponent } from "../../auth/components/set-pin.component"; import { flagEnabled } from "../../platform/flags"; -import { ElectronStateService } from "../../platform/services/electron-state.service.abstraction"; @Component({ selector: "app-settings", @@ -110,7 +110,7 @@ export class SettingsComponent implements OnInit { private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private vaultTimeoutSettingsService: VaultTimeoutSettingsService, - private stateService: ElectronStateService, + private stateService: StateService, private messagingService: MessagingService, private cryptoService: CryptoService, private modalService: ModalService, @@ -242,7 +242,7 @@ export class SettingsComponent implements OnInit { ), pin: this.userHasPinSet, biometric: await this.vaultTimeoutSettingsService.isBiometricLockSet(), - autoPromptBiometrics: !(await this.stateService.getDisableAutoBiometricsPrompt()), + autoPromptBiometrics: await firstValueFrom(this.biometricStateService.promptAutomatically$), requirePasswordOnStart: await firstValueFrom( this.biometricStateService.requirePasswordOnStart$, ), @@ -453,9 +453,9 @@ export class SettingsComponent implements OnInit { // Recommended settings for Windows Hello this.form.controls.requirePasswordOnStart.setValue(true); this.form.controls.autoPromptBiometrics.setValue(false); - await this.stateService.setDisableAutoBiometricsPrompt(true); + await this.biometricStateService.setPromptAutomatically(false); await this.biometricStateService.setRequirePasswordOnStart(true); - await this.stateService.setDismissedBiometricRequirePasswordOnStart(); + await this.biometricStateService.setDismissedRequirePasswordOnStartCallout(); } await this.cryptoService.refreshAdditionalKeys(); @@ -475,10 +475,9 @@ export class SettingsComponent implements OnInit { // require password on start must be disabled if auto prompt biometrics is enabled this.form.controls.requirePasswordOnStart.setValue(false); await this.updateRequirePasswordOnStart(); - - await this.stateService.setDisableAutoBiometricsPrompt(null); + await this.biometricStateService.setPromptAutomatically(true); } else { - await this.stateService.setDisableAutoBiometricsPrompt(true); + await this.biometricStateService.setPromptAutomatically(false); } } @@ -492,7 +491,7 @@ export class SettingsComponent implements OnInit { } else { await this.biometricStateService.setRequirePasswordOnStart(false); } - await this.stateService.setDismissedBiometricRequirePasswordOnStart(); + await this.biometricStateService.setDismissedRequirePasswordOnStartCallout(); await this.cryptoService.refreshAdditionalKeys(); } diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index aa650b70738..c7b140dd1fc 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -38,6 +38,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { SystemService } from "@bitwarden/common/platform/abstractions/system.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -147,6 +148,7 @@ export class AppComponent implements OnInit, OnDestroy { private userVerificationService: UserVerificationService, private configService: ConfigServiceAbstraction, private dialogService: DialogService, + private biometricStateService: BiometricStateService, ) {} ngOnInit() { @@ -576,6 +578,7 @@ export class AppComponent implements OnInit, OnDestroy { await this.vaultTimeoutSettingsService.clear(userBeingLoggedOut); await this.policyService.clear(userBeingLoggedOut); await this.keyConnectorService.clear(); + await this.biometricStateService.logout(userBeingLoggedOut as UserId); preLogoutActiveUserId = this.activeUserId; await this.stateService.clean({ userId: userBeingLoggedOut }); diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 06ac9e1deb9..274564489c7 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -57,7 +57,6 @@ import { ElectronRendererMessagingService } from "../../platform/services/electr import { ElectronRendererSecureStorageService } from "../../platform/services/electron-renderer-secure-storage.service"; import { ElectronRendererStorageService } from "../../platform/services/electron-renderer-storage.service"; import { ElectronStateService } from "../../platform/services/electron-state.service"; -import { ElectronStateService as ElectronStateServiceAbstraction } from "../../platform/services/electron-state.service.abstraction"; import { I18nRendererService } from "../../platform/services/i18n.renderer.service"; import { EncryptedMessageHandlerService } from "../../services/encrypted-message-handler.service"; import { NativeMessageHandlerService } from "../../services/native-message-handler.service"; @@ -140,10 +139,6 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK"); STATE_SERVICE_USE_CACHE, ], }, - { - provide: ElectronStateServiceAbstraction, - useExisting: StateServiceAbstraction, - }, { provide: FileDownloadService, useClass: DesktopFileDownloadService, diff --git a/apps/desktop/src/auth/lock.component.spec.ts b/apps/desktop/src/auth/lock.component.spec.ts index f428bda50e4..6ecf93deb84 100644 --- a/apps/desktop/src/auth/lock.component.spec.ts +++ b/apps/desktop/src/auth/lock.component.spec.ts @@ -21,12 +21,11 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { DialogService } from "@bitwarden/components"; -import { ElectronStateService } from "../platform/services/electron-state.service.abstraction"; - import { LockComponent } from "./lock.component"; // ipc mock global @@ -43,14 +42,15 @@ const isWindowVisibleMock = jest.fn(); describe("LockComponent", () => { let component: LockComponent; let fixture: ComponentFixture; - let stateServiceMock: MockProxy; + let stateServiceMock: MockProxy; + const biometricStateService = mock(); let messagingServiceMock: MockProxy; let broadcasterServiceMock: MockProxy; let platformUtilsServiceMock: MockProxy; let activatedRouteMock: MockProxy; - beforeEach(() => { - stateServiceMock = mock(); + beforeEach(async () => { + stateServiceMock = mock(); stateServiceMock.activeAccount$ = of(null); messagingServiceMock = mock(); @@ -60,9 +60,11 @@ describe("LockComponent", () => { activatedRouteMock = mock(); activatedRouteMock.queryParams = mock(); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - TestBed.configureTestingModule({ + biometricStateService.dismissedRequirePasswordOnStartCallout$ = of(false); + biometricStateService.promptAutomatically$ = of(false); + biometricStateService.promptCancelled$ = of(false); + + await TestBed.configureTestingModule({ declarations: [LockComponent, I18nPipe], providers: [ { @@ -94,7 +96,7 @@ describe("LockComponent", () => { useValue: mock(), }, { - provide: ElectronStateService, + provide: StateService, useValue: stateServiceMock, }, { @@ -143,18 +145,19 @@ describe("LockComponent", () => { }, { provide: BiometricStateService, - useValue: mock(), + useValue: biometricStateService, }, ], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); - }); - beforeEach(() => { fixture = TestBed.createComponent(LockComponent); component = fixture.componentInstance; fixture.detectChanges(); - jest.clearAllMocks(); + }); + + afterEach(() => { + jest.resetAllMocks(); }); describe("ngOnInit", () => { @@ -164,15 +167,15 @@ describe("LockComponent", () => { expect(superNgOnInitSpy).toHaveBeenCalledTimes(1); }); - it('should set "autoPromptBiometric" to true if "stateService.getDisableAutoBiometricsPrompt()" resolves to false', async () => { - stateServiceMock.getDisableAutoBiometricsPrompt.mockResolvedValue(false); + it('should set "autoPromptBiometric" to true if "biometricState.promptAutomatically$" resolves to true', async () => { + biometricStateService.promptAutomatically$ = of(true); await component.ngOnInit(); expect(component["autoPromptBiometric"]).toBe(true); }); - it('should set "autoPromptBiometric" to false if "stateService.getDisableAutoBiometricsPrompt()" resolves to true', async () => { - stateServiceMock.getDisableAutoBiometricsPrompt.mockResolvedValue(true); + it('should set "autoPromptBiometric" to false if "biometricState.promptAutomatically$" resolves to false', async () => { + biometricStateService.promptAutomatically$ = of(false); await component.ngOnInit(); expect(component["autoPromptBiometric"]).toBe(false); diff --git a/apps/desktop/src/auth/lock.component.ts b/apps/desktop/src/auth/lock.component.ts index 3f462b395d6..e88ce17ca56 100644 --- a/apps/desktop/src/auth/lock.component.ts +++ b/apps/desktop/src/auth/lock.component.ts @@ -1,6 +1,6 @@ import { Component, NgZone } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; -import { switchMap } from "rxjs"; +import { firstValueFrom, switchMap } from "rxjs"; import { LockComponent as BaseLockComponent } from "@bitwarden/angular/auth/components/lock.component"; import { PinCryptoServiceAbstraction } from "@bitwarden/auth/common"; @@ -19,12 +19,11 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { DialogService } from "@bitwarden/components"; -import { ElectronStateService } from "../platform/services/electron-state.service.abstraction"; - const BroadcasterSubscriptionId = "LockComponent"; @Component({ @@ -46,7 +45,7 @@ export class LockComponent extends BaseLockComponent { vaultTimeoutService: VaultTimeoutService, vaultTimeoutSettingsService: VaultTimeoutSettingsService, environmentService: EnvironmentService, - protected override stateService: ElectronStateService, + protected override stateService: StateService, apiService: ApiService, private route: ActivatedRoute, private broadcasterService: BroadcasterService, @@ -59,7 +58,7 @@ export class LockComponent extends BaseLockComponent { deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, userVerificationService: UserVerificationService, pinCryptoService: PinCryptoServiceAbstraction, - private biometricStateService: BiometricStateService, + biometricStateService: BiometricStateService, ) { super( router, @@ -81,12 +80,15 @@ export class LockComponent extends BaseLockComponent { deviceTrustCryptoService, userVerificationService, pinCryptoService, + biometricStateService, ); } async ngOnInit() { await super.ngOnInit(); - this.autoPromptBiometric = !(await this.stateService.getDisableAutoBiometricsPrompt()); + this.autoPromptBiometric = await firstValueFrom( + this.biometricStateService.promptAutomatically$, + ); this.biometricReady = await this.canUseBiometric(); await this.displayBiometricUpdateWarning(); @@ -140,7 +142,7 @@ export class LockComponent extends BaseLockComponent { return; } - if (await this.stateService.getBiometricPromptCancelled()) { + if (await firstValueFrom(this.biometricStateService.promptCancelled$)) { return; } @@ -162,7 +164,7 @@ export class LockComponent extends BaseLockComponent { } private async displayBiometricUpdateWarning(): Promise { - if (await this.stateService.getDismissedBiometricRequirePasswordOnStart()) { + if (await firstValueFrom(this.biometricStateService.dismissedRequirePasswordOnStartCallout$)) { return; } @@ -179,10 +181,10 @@ export class LockComponent extends BaseLockComponent { await this.biometricStateService.setRequirePasswordOnStart(response); if (response) { - await this.stateService.setDisableAutoBiometricsPrompt(true); + await this.biometricStateService.setPromptAutomatically(false); } this.supportsBiometric = await this.canUseBiometric(); - await this.stateService.setDismissedBiometricRequirePasswordOnStart(); + await this.biometricStateService.setDismissedRequirePasswordOnStartCallout(); } } diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 5c18814a0b2..f64ae8e5890 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -3,6 +3,7 @@ import * as path from "path"; import { app } from "electron"; import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { DefaultBiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state"; @@ -44,7 +45,7 @@ export class Main { memoryStorageService: MemoryStorageService; memoryStorageForStateProviders: MemoryStorageServiceForStateProviders; messagingService: ElectronMainMessagingService; - stateService: ElectronStateService; + stateService: StateService; environmentService: EnvironmentService; desktopCredentialStorageListener: DesktopCredentialStorageListener; migrationRunner: MigrationRunner; @@ -146,8 +147,11 @@ export class Main { false, // Do not use disk caching because this will get out of sync with the renderer service ); + const biometricStateService = new DefaultBiometricStateService(stateProvider); + this.windowMain = new WindowMain( this.stateService, + biometricStateService, this.logService, this.storageService, (arg) => this.processDeepLink(arg), @@ -169,8 +173,6 @@ export class Main { this.updaterMain, ); - const biometricStateService = new DefaultBiometricStateService(stateProvider); - this.biometricsService = new BiometricsService( this.i18nService, this.windowMain, diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 64eca116dd8..3154a8ccc19 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -8,6 +8,7 @@ import { WindowState } from "@bitwarden/common/models/domain/window-state"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { cleanUserAgent, @@ -36,6 +37,7 @@ export class WindowMain { constructor( private stateService: StateService, + private biometricStateService: BiometricStateService, private logService: LogService, private storageService: AbstractStorageService, private argvCallback: (argv: string[]) => void = null, @@ -90,11 +92,9 @@ export class WindowMain { // This method will be called when Electron is shutting // down the application. - app.on("before-quit", () => { + app.on("before-quit", async () => { // Allow biometric to auto-prompt on reload - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.stateService.setBiometricPromptCancelled(false); + await this.biometricStateService.resetPromptCancelled(); this.isQuitting = true; }); diff --git a/apps/desktop/src/platform/main/biometric/biometrics.service.spec.ts b/apps/desktop/src/platform/main/biometric/biometrics.service.spec.ts index 124b7db914f..c7f48aac22c 100644 --- a/apps/desktop/src/platform/main/biometric/biometrics.service.spec.ts +++ b/apps/desktop/src/platform/main/biometric/biometrics.service.spec.ts @@ -3,11 +3,11 @@ import { mock, MockProxy } from "jest-mock-extended"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { UserId } from "@bitwarden/common/types/guid"; import { WindowMain } from "../../../main/window.main"; -import { ElectronStateService } from "../../services/electron-state.service.abstraction"; import BiometricDarwinMain from "./biometric.darwin.main"; import BiometricWindowsMain from "./biometric.windows.main"; @@ -24,7 +24,7 @@ jest.mock("@bitwarden/desktop-native", () => { describe("biometrics tests", function () { const i18nService = mock(); const windowMain = mock(); - const stateService = mock(); + const stateService = mock(); const logService = mock(); const messagingService = mock(); const biometricStateService = mock(); diff --git a/apps/desktop/src/platform/main/biometric/biometrics.service.ts b/apps/desktop/src/platform/main/biometric/biometrics.service.ts index 2a6577a2ee3..301de1a9940 100644 --- a/apps/desktop/src/platform/main/biometric/biometrics.service.ts +++ b/apps/desktop/src/platform/main/biometric/biometrics.service.ts @@ -1,11 +1,11 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { UserId } from "@bitwarden/common/types/guid"; import { WindowMain } from "../../../main/window.main"; -import { ElectronStateService } from "../../services/electron-state.service.abstraction"; import { BiometricsServiceAbstraction, OsBiometricService } from "./biometrics.service.abstraction"; @@ -16,7 +16,7 @@ export class BiometricsService implements BiometricsServiceAbstraction { constructor( private i18nService: I18nService, private windowMain: WindowMain, - private stateService: ElectronStateService, + private stateService: StateService, private logService: LogService, private messagingService: MessagingService, private platform: NodeJS.Platform, diff --git a/apps/desktop/src/platform/services/electron-crypto.service.spec.ts b/apps/desktop/src/platform/services/electron-crypto.service.spec.ts index 58ea5c412ee..ba86df1d9bf 100644 --- a/apps/desktop/src/platform/services/electron-crypto.service.spec.ts +++ b/apps/desktop/src/platform/services/electron-crypto.service.spec.ts @@ -6,6 +6,7 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt. import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { makeEncString } from "@bitwarden/common/spec"; @@ -19,7 +20,6 @@ import { } from "../../../../../libs/common/spec/fake-account-service"; import { ElectronCryptoService } from "./electron-crypto.service"; -import { ElectronStateService } from "./electron-state.service.abstraction"; describe("electronCryptoService", () => { let sut: ElectronCryptoService; @@ -29,7 +29,7 @@ describe("electronCryptoService", () => { const encryptService = mock(); const platformUtilService = mock(); const logService = mock(); - const stateService = mock(); + const stateService = mock(); let accountService: FakeAccountService; let stateProvider: FakeStateProvider; const biometricStateService = mock(); diff --git a/apps/desktop/src/platform/services/electron-crypto.service.ts b/apps/desktop/src/platform/services/electron-crypto.service.ts index 184be5e1fb9..a7e46dfb1ac 100644 --- a/apps/desktop/src/platform/services/electron-crypto.service.ts +++ b/apps/desktop/src/platform/services/electron-crypto.service.ts @@ -4,6 +4,7 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt. import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -15,8 +16,6 @@ import { CsprngString } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey, MasterKey } from "@bitwarden/common/types/key"; -import { ElectronStateService } from "./electron-state.service.abstraction"; - export class ElectronCryptoService extends CryptoService { constructor( keyGenerationService: KeyGenerationService, @@ -24,7 +23,7 @@ export class ElectronCryptoService extends CryptoService { encryptService: EncryptService, platformUtilsService: PlatformUtilsService, logService: LogService, - protected override stateService: ElectronStateService, + stateService: StateService, accountService: AccountService, stateProvider: StateProvider, private biometricStateService: BiometricStateService, diff --git a/apps/desktop/src/platform/services/electron-state.service.abstraction.ts b/apps/desktop/src/platform/services/electron-state.service.abstraction.ts deleted file mode 100644 index 26b1a25f57c..00000000000 --- a/apps/desktop/src/platform/services/electron-state.service.abstraction.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { StorageOptions } from "@bitwarden/common/platform/models/domain/storage-options"; - -import { Account } from "../../models/account"; - -export abstract class ElectronStateService extends StateService { - getDismissedBiometricRequirePasswordOnStart: (options?: StorageOptions) => Promise; - setDismissedBiometricRequirePasswordOnStart: (options?: StorageOptions) => Promise; -} diff --git a/apps/desktop/src/platform/services/electron-state.service.ts b/apps/desktop/src/platform/services/electron-state.service.ts index 85182c02da1..f4399221d2d 100644 --- a/apps/desktop/src/platform/services/electron-state.service.ts +++ b/apps/desktop/src/platform/services/electron-state.service.ts @@ -7,12 +7,7 @@ import { DeviceKey } from "@bitwarden/common/types/key"; import { Account } from "../../models/account"; -import { ElectronStateService as ElectronStateServiceAbstraction } from "./electron-state.service.abstraction"; - -export class ElectronStateService - extends BaseStateService - implements ElectronStateServiceAbstraction -{ +export class ElectronStateService extends BaseStateService { private partialKeys = { deviceKey: "_deviceKey", }; @@ -23,24 +18,6 @@ export class ElectronStateService await super.addAccount(account); } - async getDismissedBiometricRequirePasswordOnStart(options?: StorageOptions): Promise { - const account = await this.getAccount( - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - return account?.settings?.dismissedBiometricRequirePasswordOnStartCallout; - } - - async setDismissedBiometricRequirePasswordOnStart(options?: StorageOptions): Promise { - const account = await this.getAccount( - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - account.settings.dismissedBiometricRequirePasswordOnStartCallout = true; - await this.saveAccount( - account, - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - } - override async getDeviceKey(options?: StorageOptions): Promise { options = this.reconcileOptions(options, await this.defaultSecureStorageOptions()); if (options?.userId == null) { diff --git a/apps/desktop/src/services/encrypted-message-handler.service.ts b/apps/desktop/src/services/encrypted-message-handler.service.ts index 106ef8e6a6a..e38339d5ad0 100644 --- a/apps/desktop/src/services/encrypted-message-handler.service.ts +++ b/apps/desktop/src/services/encrypted-message-handler.service.ts @@ -5,6 +5,7 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -24,11 +25,10 @@ import { GenerateResponse } from "../models/native-messaging/encrypted-message-r import { MessageResponseData } from "../models/native-messaging/encrypted-message-responses/message-response-data"; import { SuccessStatusResponse } from "../models/native-messaging/encrypted-message-responses/success-status-response"; import { UserStatusErrorResponse } from "../models/native-messaging/encrypted-message-responses/user-status-error-response"; -import { ElectronStateService } from "../platform/services/electron-state.service"; export class EncryptedMessageHandlerService { constructor( - private stateService: ElectronStateService, + private stateService: StateService, private authService: AuthService, private cipherService: CipherService, private policyService: PolicyService, diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index 25a8675d838..1a81ce555b7 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -20,7 +20,9 @@ import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.se import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; @@ -82,6 +84,7 @@ export class AppComponent implements OnDestroy, OnInit { private keyConnectorService: KeyConnectorService, private configService: ConfigServiceAbstraction, private dialogService: DialogService, + private biometricStateService: BiometricStateService, ) {} ngOnInit() { @@ -265,6 +268,7 @@ export class AppComponent implements OnDestroy, OnInit { this.policyService.clear(userId), this.passwordGenerationService.clear(), this.keyConnectorService.clear(), + this.biometricStateService.logout(userId as UserId), ]); this.searchService.clearIndex(); diff --git a/apps/web/src/app/auth/lock.component.ts b/apps/web/src/app/auth/lock.component.ts index 7088623aaf8..c4f8d276bb0 100644 --- a/apps/web/src/app/auth/lock.component.ts +++ b/apps/web/src/app/auth/lock.component.ts @@ -17,6 +17,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { DialogService } from "@bitwarden/components"; @@ -45,6 +46,7 @@ export class LockComponent extends BaseLockComponent { deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, userVerificationService: UserVerificationService, pinCryptoService: PinCryptoServiceAbstraction, + biometricStateService: BiometricStateService, ) { super( router, @@ -66,6 +68,7 @@ export class LockComponent extends BaseLockComponent { deviceTrustCryptoService, userVerificationService, pinCryptoService, + biometricStateService, ); } diff --git a/libs/angular/src/auth/components/lock.component.ts b/libs/angular/src/auth/components/lock.component.ts index 3bc46b86ad4..d5da3e826eb 100644 --- a/libs/angular/src/auth/components/lock.component.ts +++ b/libs/angular/src/auth/components/lock.component.ts @@ -23,6 +23,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service"; import { HashPurpose, KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { PinLockType } from "@bitwarden/common/services/vault-timeout/vault-timeout-settings.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; @@ -73,6 +74,7 @@ export class LockComponent implements OnInit, OnDestroy { protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, protected userVerificationService: UserVerificationService, protected pinCryptoService: PinCryptoServiceAbstraction, + protected biometricStateService: BiometricStateService, ) {} async ngOnInit() { @@ -117,7 +119,7 @@ export class LockComponent implements OnInit, OnDestroy { return; } - await this.stateService.setBiometricPromptCancelled(true); + await this.biometricStateService.setPromptCancelled(); const userKey = await this.cryptoService.getUserKeyFromStorage(KeySuffixOptions.Biometric); if (userKey) { @@ -274,7 +276,7 @@ export class LockComponent implements OnInit, OnDestroy { private async doContinue(evaluatePasswordAfterUnlock: boolean) { await this.stateService.setEverBeenUnlocked(true); - await this.stateService.setBiometricPromptCancelled(false); + await this.biometricStateService.resetPromptCancelled(); this.messagingService.send("unlocked"); if (evaluatePasswordAfterUnlock) { diff --git a/libs/common/spec/fake-state.ts b/libs/common/spec/fake-state.ts index 96f3d41dd1f..38a28b1f025 100644 --- a/libs/common/spec/fake-state.ts +++ b/libs/common/spec/fake-state.ts @@ -66,6 +66,7 @@ export class FakeGlobalState implements GlobalState { }); updateMock = this.update as jest.MockedFunction; + /** Tracks update values resolved by `FakeState.update` */ nextMock = jest.fn(); get state$() { @@ -128,6 +129,7 @@ export class FakeSingleUserState implements SingleUserState { updateMock = this.update as jest.MockedFunction; + /** Tracks update values resolved by `FakeState.update` */ nextMock = jest.fn(); private _keyDefinition: KeyDefinition | null = null; get keyDefinition() { @@ -190,6 +192,7 @@ export class FakeActiveUserState implements ActiveUserState { updateMock = this.update as jest.MockedFunction; + /** Tracks update values resolved by `FakeState.update` */ nextMock = jest.fn(); private _keyDefinition: KeyDefinition | null = null; diff --git a/libs/common/src/platform/abstractions/state.service.ts b/libs/common/src/platform/abstractions/state.service.ts index 8de781674f8..2611acf5c32 100644 --- a/libs/common/src/platform/abstractions/state.service.ts +++ b/libs/common/src/platform/abstractions/state.service.ts @@ -169,18 +169,6 @@ export abstract class StateService { * @deprecated For migration purposes only, use setUserKeyBiometric instead */ setCryptoMasterKeyBiometric: (value: BiometricKey, options?: StorageOptions) => Promise; - /** - * Gets a flag for if the biometrics process has been cancelled. - * Process reload occurs when biometrics is cancelled, so we store to disk to prevent - * it from reprompting and creating a loop. - */ - getBiometricPromptCancelled: (options?: StorageOptions) => Promise; - /** - * Sets a flag for if the biometrics process has been cancelled. - * Process reload occurs when biometrics is cancelled, so we store to disk to prevent - * it from reprompting and creating a loop. - */ - setBiometricPromptCancelled: (value: boolean, options?: StorageOptions) => Promise; getDecryptedCiphers: (options?: StorageOptions) => Promise; setDecryptedCiphers: (value: CipherView[], options?: StorageOptions) => Promise; getDecryptedPasswordGenerationHistory: ( @@ -218,8 +206,6 @@ export abstract class StateService { setDefaultUriMatch: (value: UriMatchType, options?: StorageOptions) => Promise; getDisableAddLoginNotification: (options?: StorageOptions) => Promise; setDisableAddLoginNotification: (value: boolean, options?: StorageOptions) => Promise; - getDisableAutoBiometricsPrompt: (options?: StorageOptions) => Promise; - setDisableAutoBiometricsPrompt: (value: boolean, options?: StorageOptions) => Promise; getDisableBadgeCounter: (options?: StorageOptions) => Promise; setDisableBadgeCounter: (value: boolean, options?: StorageOptions) => Promise; getDisableChangedPasswordNotification: (options?: StorageOptions) => Promise; diff --git a/libs/common/src/platform/biometrics/biometric-state.service.spec.ts b/libs/common/src/platform/biometrics/biometric-state.service.spec.ts index 5752f692717..44be94983f9 100644 --- a/libs/common/src/platform/biometrics/biometric-state.service.spec.ts +++ b/libs/common/src/platform/biometrics/biometric-state.service.spec.ts @@ -8,7 +8,13 @@ import { UserId } from "../../types/guid"; import { EncryptedString } from "../models/domain/enc-string"; import { BiometricStateService, DefaultBiometricStateService } from "./biometric-state.service"; -import { ENCRYPTED_CLIENT_KEY_HALF, REQUIRE_PASSWORD_ON_START } from "./biometric.state"; +import { + DISMISSED_REQUIRE_PASSWORD_ON_START_CALLOUT, + ENCRYPTED_CLIENT_KEY_HALF, + PROMPT_AUTOMATICALLY, + PROMPT_CANCELLED, + REQUIRE_PASSWORD_ON_START, +} from "./biometric.state"; describe("BiometricStateService", () => { let sut: BiometricStateService; @@ -96,4 +102,56 @@ describe("BiometricStateService", () => { expect(await sut.getRequirePasswordOnStart(userId)).toBe(true); }); }); + + describe("require password on start callout", () => { + it("should be false when not set", async () => { + expect(await firstValueFrom(sut.dismissedRequirePasswordOnStartCallout$)).toBe(false); + }); + + it("should be true when set", async () => { + await sut.setDismissedRequirePasswordOnStartCallout(); + + expect(await firstValueFrom(sut.dismissedRequirePasswordOnStartCallout$)).toBe(true); + }); + + it("should update disk state", async () => { + await sut.setDismissedRequirePasswordOnStartCallout(); + + expect( + stateProvider.activeUser.getFake(DISMISSED_REQUIRE_PASSWORD_ON_START_CALLOUT).nextMock, + ).toHaveBeenCalledWith([userId, true]); + }); + }); + + describe("prompt cancelled", () => { + test("observable should be updated", async () => { + await sut.setPromptCancelled(); + + expect(await firstValueFrom(sut.promptCancelled$)).toBe(true); + }); + + it("should update state with set", async () => { + await sut.setPromptCancelled(); + + const nextMock = stateProvider.activeUser.getFake(PROMPT_CANCELLED).nextMock; + expect(nextMock).toHaveBeenCalledWith([userId, true]); + expect(nextMock).toHaveBeenCalledTimes(1); + }); + }); + + describe("prompt automatically", () => { + test("observable should be updated", async () => { + await sut.setPromptAutomatically(true); + + expect(await firstValueFrom(sut.promptAutomatically$)).toBe(true); + }); + + it("should update state with setPromptAutomatically", async () => { + await sut.setPromptAutomatically(true); + + const nextMock = stateProvider.activeUser.getFake(PROMPT_AUTOMATICALLY).nextMock; + expect(nextMock).toHaveBeenCalledWith([userId, true]); + expect(nextMock).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/libs/common/src/platform/biometrics/biometric-state.service.ts b/libs/common/src/platform/biometrics/biometric-state.service.ts index 0007a5f2108..7033184dabb 100644 --- a/libs/common/src/platform/biometrics/biometric-state.service.ts +++ b/libs/common/src/platform/biometrics/biometric-state.service.ts @@ -4,7 +4,13 @@ import { UserId } from "../../types/guid"; import { EncryptedString, EncString } from "../models/domain/enc-string"; import { ActiveUserState, StateProvider } from "../state"; -import { ENCRYPTED_CLIENT_KEY_HALF, REQUIRE_PASSWORD_ON_START } from "./biometric.state"; +import { + ENCRYPTED_CLIENT_KEY_HALF, + REQUIRE_PASSWORD_ON_START, + DISMISSED_REQUIRE_PASSWORD_ON_START_CALLOUT, + PROMPT_AUTOMATICALLY, + PROMPT_CANCELLED, +} from "./biometric.state"; export abstract class BiometricStateService { /** @@ -20,6 +26,24 @@ export abstract class BiometricStateService { * tracks the currently active user */ requirePasswordOnStart$: Observable; + /** + * Indicates the user has been warned about the security implications of using biometrics and, depending on the OS, + * + * tracks the currently active user. + */ + dismissedRequirePasswordOnStartCallout$: Observable; + /** + * Whether the user has cancelled the biometric prompt. + * + * tracks the currently active user + */ + promptCancelled$: Observable; + /** + * Whether the user has elected to automatically prompt for biometrics. + * + * tracks the currently active user + */ + promptAutomatically$: Observable; /** * Updates the require password on start state for the currently active user. @@ -32,13 +56,38 @@ export abstract class BiometricStateService { abstract getEncryptedClientKeyHalf(userId: UserId): Promise; abstract getRequirePasswordOnStart(userId: UserId): Promise; abstract removeEncryptedClientKeyHalf(userId: UserId): Promise; + /** + * Updates the active user's state to reflect that they've been warned about requiring password on start. + */ + abstract setDismissedRequirePasswordOnStartCallout(): Promise; + /** + * Updates the active user's state to reflect that they've cancelled the biometric prompt this lock. + */ + abstract setPromptCancelled(): Promise; + /** + * Resets the active user's state to reflect that they haven't cancelled the biometric prompt this lock. + */ + abstract resetPromptCancelled(): Promise; + /** + * Updates the currently active user's setting for auto prompting for biometrics on application start and lock + * @param prompt Whether or not to prompt for biometrics on application start. + */ + abstract setPromptAutomatically(prompt: boolean): Promise; + + abstract logout(userId: UserId): Promise; } export class DefaultBiometricStateService implements BiometricStateService { private requirePasswordOnStartState: ActiveUserState; private encryptedClientKeyHalfState: ActiveUserState; + private dismissedRequirePasswordOnStartCalloutState: ActiveUserState; + private promptCancelledState: ActiveUserState; + private promptAutomaticallyState: ActiveUserState; encryptedClientKeyHalf$: Observable; requirePasswordOnStart$: Observable; + dismissedRequirePasswordOnStartCallout$: Observable; + promptCancelled$: Observable; + promptAutomatically$: Observable; constructor(private stateProvider: StateProvider) { this.requirePasswordOnStartState = this.stateProvider.getActive(REQUIRE_PASSWORD_ON_START); @@ -50,6 +99,17 @@ export class DefaultBiometricStateService implements BiometricStateService { this.encryptedClientKeyHalf$ = this.encryptedClientKeyHalfState.state$.pipe( map(encryptedClientKeyHalfToEncString), ); + + this.dismissedRequirePasswordOnStartCalloutState = this.stateProvider.getActive( + DISMISSED_REQUIRE_PASSWORD_ON_START_CALLOUT, + ); + this.dismissedRequirePasswordOnStartCallout$ = + this.dismissedRequirePasswordOnStartCalloutState.state$.pipe(map((v) => !!v)); + + this.promptCancelledState = this.stateProvider.getActive(PROMPT_CANCELLED); + this.promptCancelled$ = this.promptCancelledState.state$.pipe(map((v) => !!v)); + this.promptAutomaticallyState = this.stateProvider.getActive(PROMPT_AUTOMATICALLY); + this.promptAutomatically$ = this.promptAutomaticallyState.state$.pipe(map((v) => !!v)); } async setRequirePasswordOnStart(value: boolean): Promise { @@ -97,6 +157,25 @@ export class DefaultBiometricStateService implements BiometricStateService { async logout(userId: UserId): Promise { await this.stateProvider.getUser(userId, ENCRYPTED_CLIENT_KEY_HALF).update(() => null); + await this.stateProvider.getUser(userId, PROMPT_CANCELLED).update(() => null); + // Persist auto prompt setting through logout + // Persist dismissed require password on start callout through logout + } + + async setDismissedRequirePasswordOnStartCallout(): Promise { + await this.dismissedRequirePasswordOnStartCalloutState.update(() => true); + } + + async setPromptCancelled(): Promise { + await this.promptCancelledState.update(() => true); + } + + async resetPromptCancelled(): Promise { + await this.promptCancelledState.update(() => null); + } + + async setPromptAutomatically(prompt: boolean): Promise { + await this.promptAutomaticallyState.update(() => prompt); } } diff --git a/libs/common/src/platform/biometrics/biometric.state.spec.ts b/libs/common/src/platform/biometrics/biometric.state.spec.ts index e36b5f434fd..c868a5b927e 100644 --- a/libs/common/src/platform/biometrics/biometric.state.spec.ts +++ b/libs/common/src/platform/biometrics/biometric.state.spec.ts @@ -1,25 +1,36 @@ -import { ENCRYPTED_CLIENT_KEY_HALF, REQUIRE_PASSWORD_ON_START } from "./biometric.state"; +import { EncryptedString } from "../models/domain/enc-string"; +import { KeyDefinition } from "../state"; -describe("require password on start", () => { - const sut = REQUIRE_PASSWORD_ON_START; +import { + DISMISSED_REQUIRE_PASSWORD_ON_START_CALLOUT, + ENCRYPTED_CLIENT_KEY_HALF, + PROMPT_AUTOMATICALLY, + PROMPT_CANCELLED, + REQUIRE_PASSWORD_ON_START, +} from "./biometric.state"; - it("should deserialize require password on start state", () => { - const requirePasswordOnStart = "requirePasswordOnStart"; - - const result = sut.deserializer(JSON.parse(JSON.stringify(requirePasswordOnStart))); - - expect(result).toEqual(requirePasswordOnStart); - }); -}); - -describe("encrypted client key half", () => { - const sut = ENCRYPTED_CLIENT_KEY_HALF; - - it("should deserialize encrypted client key half state", () => { - const encryptedClientKeyHalf = "encryptedClientKeyHalf"; - - const result = sut.deserializer(JSON.parse(JSON.stringify(encryptedClientKeyHalf))); - - expect(result).toEqual(encryptedClientKeyHalf); - }); -}); +describe.each([ + [ENCRYPTED_CLIENT_KEY_HALF, "encryptedClientKeyHalf"], + [DISMISSED_REQUIRE_PASSWORD_ON_START_CALLOUT, true], + [PROMPT_CANCELLED, true], + [PROMPT_AUTOMATICALLY, true], + [REQUIRE_PASSWORD_ON_START, true], +])( + "deserializes state %s", + ( + ...args: [KeyDefinition, EncryptedString] | [KeyDefinition, boolean] + ) => { + it("should deserialize state", () => { + const [keyDefinition, state] = args; + // Need to type check to avoid TS error due to array values being unions instead of guaranteed tuple pairs + if (typeof state === "boolean") { + const deserialized = keyDefinition.deserializer(JSON.parse(JSON.stringify(state))); + expect(deserialized).toEqual(state); + return; + } else { + const deserialized = keyDefinition.deserializer(JSON.parse(JSON.stringify(state))); + expect(deserialized).toEqual(state); + } + }); + }, +); diff --git a/libs/common/src/platform/biometrics/biometric.state.ts b/libs/common/src/platform/biometrics/biometric.state.ts index 2c231b9e769..84a4c13a5ff 100644 --- a/libs/common/src/platform/biometrics/biometric.state.ts +++ b/libs/common/src/platform/biometrics/biometric.state.ts @@ -28,3 +28,38 @@ export const ENCRYPTED_CLIENT_KEY_HALF = new KeyDefinition( deserializer: (obj) => obj, }, ); + +/** + * Indicates the user has been warned about the security implications of using biometrics and, depending on the OS, + * recommended to require a password on first unlock of an application instance. + */ +export const DISMISSED_REQUIRE_PASSWORD_ON_START_CALLOUT = new KeyDefinition( + BIOMETRIC_SETTINGS_DISK, + "dismissedBiometricRequirePasswordOnStartCallout", + { + deserializer: (obj) => obj, + }, +); + +/** + * Stores whether the user has elected to cancel the biometric prompt. This is stored on disk due to process-reload + * wiping memory state. We don't want to prompt the user again if they've elected to cancel. + */ +export const PROMPT_CANCELLED = new KeyDefinition( + BIOMETRIC_SETTINGS_DISK, + "promptCancelled", + { + deserializer: (obj) => obj, + }, +); + +/** + * Stores whether the user has elected to automatically prompt for biometric unlock on application start. + */ +export const PROMPT_AUTOMATICALLY = new KeyDefinition( + BIOMETRIC_SETTINGS_DISK, + "promptAutomatically", + { + deserializer: (obj) => obj, + }, +); diff --git a/libs/common/src/platform/models/domain/account.ts b/libs/common/src/platform/models/domain/account.ts index 40fc2e623ba..9cafabbda4c 100644 --- a/libs/common/src/platform/models/domain/account.ts +++ b/libs/common/src/platform/models/domain/account.ts @@ -203,7 +203,6 @@ export class AccountSettings { biometricUnlock?: boolean; clearClipboard?: number; defaultUriMatch?: UriMatchType; - disableAutoBiometricsPrompt?: boolean; disableBadgeCounter?: boolean; disableGa?: boolean; dontShowCardsCurrentTab?: boolean; @@ -227,7 +226,6 @@ export class AccountSettings { avatarColor?: string; smOnboardingTasks?: Record>; trustDeviceChoiceForDecryption?: boolean; - biometricPromptCancelled?: boolean; /** @deprecated July 2023, left for migration purposes*/ pinProtected?: EncryptionPair = new EncryptionPair(); diff --git a/libs/common/src/platform/services/state.service.ts b/libs/common/src/platform/services/state.service.ts index 96005ef3942..050948293b7 100644 --- a/libs/common/src/platform/services/state.service.ts +++ b/libs/common/src/platform/services/state.service.ts @@ -775,24 +775,6 @@ export class StateService< await this.saveSecureStorageKey(partialKeys.biometricKey, value, options); } - async getBiometricPromptCancelled(options?: StorageOptions): Promise { - const account = await this.getAccount( - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - return account?.settings?.biometricPromptCancelled; - } - - async setBiometricPromptCancelled(value: boolean, options?: StorageOptions): Promise { - const account = await this.getAccount( - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - account.settings.biometricPromptCancelled = value; - await this.saveAccount( - account, - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - } - @withPrototypeForArrayMembers(CipherView, CipherView.fromJSON) async getDecryptedCiphers(options?: StorageOptions): Promise { return ( @@ -928,24 +910,6 @@ export class StateService< ); } - async getDisableAutoBiometricsPrompt(options?: StorageOptions): Promise { - return ( - (await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))) - ?.settings?.disableAutoBiometricsPrompt ?? false - ); - } - - async setDisableAutoBiometricsPrompt(value: boolean, options?: StorageOptions): Promise { - const account = await this.getAccount( - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - account.settings.disableAutoBiometricsPrompt = value; - await this.saveAccount( - account, - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - } - async getDisableBadgeCounter(options?: StorageOptions): Promise { return ( (await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))) diff --git a/libs/common/src/state-migrations/migrate.ts b/libs/common/src/state-migrations/migrate.ts index 72e8b34edb0..7192c6e070a 100644 --- a/libs/common/src/state-migrations/migrate.ts +++ b/libs/common/src/state-migrations/migrate.ts @@ -17,6 +17,7 @@ import { RequirePasswordOnStartMigrator } from "./migrations/19-migrate-require- import { PrivateKeyMigrator } from "./migrations/20-move-private-key-to-state-providers"; import { CollectionMigrator } from "./migrations/21-move-collections-state-to-state-provider"; import { CollapsedGroupingsMigrator } from "./migrations/22-move-collapsed-groupings-to-state-provider"; +import { MoveBiometricPromptsToStateProviders } from "./migrations/23-move-biometric-prompts-to-state-providers"; import { FixPremiumMigrator } from "./migrations/3-fix-premium"; import { RemoveEverBeenUnlockedMigrator } from "./migrations/4-remove-ever-been-unlocked"; import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org-keys"; @@ -27,7 +28,7 @@ import { MoveBrowserSettingsToGlobal } from "./migrations/9-move-browser-setting import { MinVersionMigrator } from "./migrations/min-version"; export const MIN_VERSION = 2; -export const CURRENT_VERSION = 22; +export const CURRENT_VERSION = 23; export type MinVersion = typeof MIN_VERSION; export function createMigrationBuilder() { @@ -52,7 +53,8 @@ export function createMigrationBuilder() { .with(RequirePasswordOnStartMigrator, 18, 19) .with(PrivateKeyMigrator, 19, 20) .with(CollectionMigrator, 20, 21) - .with(CollapsedGroupingsMigrator, 21, CURRENT_VERSION); + .with(CollapsedGroupingsMigrator, 21, 22) + .with(MoveBiometricPromptsToStateProviders, 22, CURRENT_VERSION); } export async function currentVersion( diff --git a/libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.spec.ts b/libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.spec.ts new file mode 100644 index 00000000000..d041517ac68 --- /dev/null +++ b/libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.spec.ts @@ -0,0 +1,131 @@ +import { MockProxy, any } from "jest-mock-extended"; + +import { MigrationHelper } from "../migration-helper"; +import { mockMigrationHelper } from "../migration-helper.spec"; + +import { + MoveBiometricPromptsToStateProviders, + DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, + PROMPT_AUTOMATICALLY, +} from "./23-move-biometric-prompts-to-state-providers"; + +function exampleJSON() { + return { + global: { + otherStuff: "otherStuff1", + }, + authenticatedAccounts: ["user-1", "user-2", "user-3"], + "user-1": { + settings: { + disableAutoBiometricsPrompt: false, + dismissedBiometricRequirePasswordOnStartCallout: true, + otherStuff: "otherStuff2", + }, + otherStuff: "otherStuff3", + }, + "user-2": { + otherStuff: "otherStuff4", + }, + }; +} + +function rollbackJSON() { + return { + "user_user-1_biometricSettings_dismissedBiometricRequirePasswordOnStartCallout": true, + "user_user-1_biometricSettings_promptAutomatically": "false", + global: { + otherStuff: "otherStuff1", + }, + authenticatedAccounts: ["user-1", "user-2", "user-3"], + "user-1": { + settings: { + otherStuff: "otherStuff2", + }, + otherStuff: "otherStuff3", + }, + "user-2": { + otherStuff: "otherStuff4", + }, + }; +} + +describe("MoveBiometricPromptsToStateProviders migrator", () => { + let helper: MockProxy; + let sut: MoveBiometricPromptsToStateProviders; + + describe("migrate", () => { + beforeEach(() => { + helper = mockMigrationHelper(exampleJSON(), 22); + sut = new MoveBiometricPromptsToStateProviders(22, 23); + }); + + it("should remove biometricUnlock, dismissedBiometricRequirePasswordOnStartCallout, and biometricEncryptionClientKeyHalf from all accounts", async () => { + await sut.migrate(helper); + expect(helper.set).toHaveBeenCalledTimes(2); + expect(helper.set).toHaveBeenCalledWith("user-1", { + settings: { + otherStuff: "otherStuff2", + }, + otherStuff: "otherStuff3", + }); + expect(helper.set).toHaveBeenCalledWith("user-2", { + otherStuff: "otherStuff4", + }); + }); + + it("should set dismissedBiometricRequirePasswordOnStartCallout value for account that have it", async () => { + await sut.migrate(helper); + + expect(helper.setToUser).toHaveBeenCalledWith( + "user-1", + DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, + true, + ); + }); + + it("should not call extra setToUser", async () => { + await sut.migrate(helper); + + expect(helper.setToUser).toHaveBeenCalledTimes(2); + }); + }); + + describe("rollback", () => { + beforeEach(() => { + helper = mockMigrationHelper(rollbackJSON(), 23); + sut = new MoveBiometricPromptsToStateProviders(22, 23); + }); + + it.each([DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, PROMPT_AUTOMATICALLY])( + "should null out new values %s", + async (keyDefinition) => { + await sut.rollback(helper); + + expect(helper.setToUser).toHaveBeenCalledWith("user-1", keyDefinition, null); + }, + ); + + it("should add explicit value back to accounts", async () => { + await sut.rollback(helper); + + expect(helper.set).toHaveBeenCalledTimes(1); + expect(helper.set).toHaveBeenCalledWith("user-1", { + settings: { + disableAutoBiometricsPrompt: false, + dismissedBiometricRequirePasswordOnStartCallout: true, + otherStuff: "otherStuff2", + }, + otherStuff: "otherStuff3", + }); + }); + + it.each(["user-2", "user-3"])( + "should not try to restore values to missing accounts", + async (userId) => { + await sut.rollback(helper); + + expect(helper.set).not.toHaveBeenCalledWith(userId, any()); + }, + ); + }); +}); diff --git a/libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.ts b/libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.ts new file mode 100644 index 00000000000..f95ccaf7fff --- /dev/null +++ b/libs/common/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.ts @@ -0,0 +1,99 @@ +import { KeyDefinitionLike, MigrationHelper } from "../migration-helper"; +import { Migrator } from "../migrator"; + +type ExpectedAccountType = { + settings?: { + disableAutoBiometricsPrompt?: boolean; + dismissedBiometricRequirePasswordOnStartCallout?: boolean; + }; +}; + +// prompt cancelled is refreshed on every app start/quit/unlock, so we don't need to migrate it + +export const DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT: KeyDefinitionLike = { + key: "dismissedBiometricRequirePasswordOnStartCallout", + stateDefinition: { name: "biometricSettings" }, +}; + +export const PROMPT_AUTOMATICALLY: KeyDefinitionLike = { + key: "promptAutomatically", + stateDefinition: { name: "biometricSettings" }, +}; + +export class MoveBiometricPromptsToStateProviders extends Migrator<22, 23> { + async migrate(helper: MigrationHelper): Promise { + const legacyAccounts = await helper.getAccounts(); + + await Promise.all( + legacyAccounts.map(async ({ userId, account }) => { + if (account == null) { + return; + } + // Move account data + + if (account?.settings?.dismissedBiometricRequirePasswordOnStartCallout != null) { + await helper.setToUser( + userId, + DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, + account.settings.dismissedBiometricRequirePasswordOnStartCallout, + ); + } + + if (account?.settings?.disableAutoBiometricsPrompt != null) { + await helper.setToUser( + userId, + PROMPT_AUTOMATICALLY, + !account.settings.disableAutoBiometricsPrompt, + ); + } + + // Delete old account data + delete account?.settings?.dismissedBiometricRequirePasswordOnStartCallout; + delete account?.settings?.disableAutoBiometricsPrompt; + await helper.set(userId, account); + }), + ); + } + + async rollback(helper: MigrationHelper): Promise { + async function rollbackUser(userId: string, account: ExpectedAccountType) { + let updatedAccount = false; + + const userDismissed = await helper.getFromUser( + userId, + DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, + ); + + if (userDismissed) { + account ??= {}; + account.settings ??= {}; + + updatedAccount = true; + account.settings.dismissedBiometricRequirePasswordOnStartCallout = userDismissed; + await helper.setToUser(userId, DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, null); + } + + const userPromptAutomatically = await helper.getFromUser( + userId, + PROMPT_AUTOMATICALLY, + ); + + if (userPromptAutomatically != null) { + account ??= {}; + account.settings ??= {}; + + updatedAccount = true; + account.settings.disableAutoBiometricsPrompt = !userPromptAutomatically; + await helper.setToUser(userId, PROMPT_AUTOMATICALLY, null); + } + + if (updatedAccount) { + await helper.set(userId, account); + } + } + + const accounts = await helper.getAccounts(); + + await Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account))); + } +} From fa43d8c55eea2bfbe28fa50dc27f2e9788724d7a Mon Sep 17 00:00:00 2001 From: Jake Fink Date: Fri, 23 Feb 2024 10:19:15 -0500 Subject: [PATCH 008/124] add missing arg to browser crypto (#8068) --- apps/browser/src/popup/services/services.module.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 55457d1c70f..92d9167df4a 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -262,6 +262,7 @@ function getBgService(service: keyof MainBackground) { { provide: CryptoService, useFactory: ( + keyGenerationService: KeyGenerationService, cryptoFunctionService: CryptoFunctionService, encryptService: EncryptService, platformUtilsService: PlatformUtilsService, @@ -271,6 +272,7 @@ function getBgService(service: keyof MainBackground) { stateProvider: StateProvider, ) => { const cryptoService = new BrowserCryptoService( + keyGenerationService, cryptoFunctionService, encryptService, platformUtilsService, From 43d1174a067db1934aa89e469de3c22e4842c4e0 Mon Sep 17 00:00:00 2001 From: Will Martin Date: Fri, 23 Feb 2024 10:51:17 -0500 Subject: [PATCH 009/124] [CL-169] add bit-section component (#8062) --- libs/components/src/index.ts | 1 + libs/components/src/section/index.ts | 1 + .../src/section/section.component.ts | 14 ++++++++ .../components/src/section/section.stories.ts | 35 +++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 libs/components/src/section/index.ts create mode 100644 libs/components/src/section/section.component.ts create mode 100644 libs/components/src/section/section.stories.ts diff --git a/libs/components/src/index.ts b/libs/components/src/index.ts index 6e8180bf76d..de7b02c7670 100644 --- a/libs/components/src/index.ts +++ b/libs/components/src/index.ts @@ -24,6 +24,7 @@ export * from "./popover"; export * from "./progress"; export * from "./radio-button"; export * from "./search"; +export * from "./section"; export * from "./select"; export * from "./table"; export * from "./tabs"; diff --git a/libs/components/src/section/index.ts b/libs/components/src/section/index.ts new file mode 100644 index 00000000000..ea2aa32a22f --- /dev/null +++ b/libs/components/src/section/index.ts @@ -0,0 +1 @@ +export * from "./section.component"; diff --git a/libs/components/src/section/section.component.ts b/libs/components/src/section/section.component.ts new file mode 100644 index 00000000000..a681dcf7d95 --- /dev/null +++ b/libs/components/src/section/section.component.ts @@ -0,0 +1,14 @@ +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; + +@Component({ + selector: "bit-section", + standalone: true, + imports: [CommonModule], + template: ` +
+ +
+ `, +}) +export class SectionComponent {} diff --git a/libs/components/src/section/section.stories.ts b/libs/components/src/section/section.stories.ts new file mode 100644 index 00000000000..fb9948e9bec --- /dev/null +++ b/libs/components/src/section/section.stories.ts @@ -0,0 +1,35 @@ +import { Meta, StoryObj, componentWrapperDecorator, moduleMetadata } from "@storybook/angular"; + +import { TypographyModule } from "../typography"; + +import { SectionComponent } from "./section.component"; + +export default { + title: "Component Library/Section", + component: SectionComponent, + decorators: [ + moduleMetadata({ + imports: [TypographyModule], + }), + componentWrapperDecorator((story) => `
${story}
`), + ], +} as Meta; + +type Story = StoryObj; + +/** Sections are simple containers that apply a bottom margin. They often contain a heading. */ +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + +

Foo

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex.

+
+ +

Bar

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex.

+
+ `, + }), +}; From 3367339f9ba73ab6718ca949750e685e21738bf9 Mon Sep 17 00:00:00 2001 From: Cesar Gonzalez Date: Fri, 23 Feb 2024 10:50:11 -0600 Subject: [PATCH 010/124] [PM-2753] Prompt to Save New Login Credentials Silently Drops Data on Network Error (#7730) * [PM-673] Safari Notification Bar Does Not Show Folders * [PM-673] Refactoring Context Menu Implementations to Ensure Pages with No Logins Can Dismiss Notification Bar * [PM-673] Refactoring typing information for the LockedVaultPendingNotificationsItem typing * [PM-673] Refactoring typing information for notification background * [PM-673] Finishing out typing for potential extension messages to the notification bar; * [PM-673] Working through implementation details for the notification background * [PM-673] Fixing issues present with messaging re-implementation * [PM-673] Fixing issue with folders not populating within Safari notification bar * [PM-673] Fixing jest test issues present within implementation * [PM-673] Fixing issue present with webVaultUrl vulnerability * [PM-673] Fixing XSS Vulnerability within Notification Bar; * [PM-5670] Putting together a partial implementation for having messages appear on network error within the notification bar * [PM-673] Incorporating status update for when user has successfully saved credentials * [PM-673] Incorporating status update for when user has successfully saved credentials * [PM-5949] Refactor typing information for notification bar * [PM-5949] Fix jest tests for overlay background * [PM-5949] Removing unnused typing data * [PM-5949] Fixing lint error * [PM-5949] Adding jest tests for convertAddLoginQueueMessageToCipherView method * [PM-5949] Fixing jest test for overlay * [PM-5950] Fix Context Menu Update Race Condition and Refactor Implementation * [PM-5950] Adding jest test for cipherContextMenu.update method * [PM-5950] Adding documentation for method within MainContextMenuHandler * [PM-5950] Adding jest tests for the mainContextMenuHandler * [PM-673] Stripping unnecessary work for network drop issue * [PM-673] Stripping unnecessary work for network drop issue * [PM-2753] Prompt to Save New Login Credentials Silently Drops Data on Network Error * [PM-673] Stripping out work done for another ticket * [PM-5950] Removing unnecessary return value from MainContextMenuHandler.create method * [PM-673] Implementing unit test coverage for newly introduced logic * [PM-673] Implementing unit test coverage for newly introduced logic * [PM-673] Implementing unit test coverage for newly introduced logic * [PM-673] Implementing unit test coverage for newly introduced logic * [PM-2753] Implementing jest tests to validate logic changes * [PM-2753] Implementing jest tests to validate logic changes * [PM-2753] Implementing jest tests to validate logic changes * [PM-2753] Implementing jest tests to validate logic changes * [PM-2753] Incorporating addition of green and red borders when success or error events occur * [PM-5950] Fixing unawaited context menu promise * [PM-673] Merging changes in from main and fixing merge conflicts * [PM-2753] Merging work in from main and resolving merge conflicts * [PM-673] Fixing issue where updates to the added login were not triggering correctly * [PM-673] Merging changes in from main and fixing merge conflicts --- apps/browser/src/_locales/en/messages.json | 16 +- .../abstractions/notification.background.ts | 3 + .../notification.background.spec.ts | 419 ++++++++++++++++++ .../background/notification.background.ts | 102 +++-- .../src/autofill/content/notification-bar.ts | 12 + .../abstractions/notification-bar.ts | 13 + .../src/autofill/notification/bar.html | 6 +- .../src/autofill/notification/bar.scss | 12 + apps/browser/src/autofill/notification/bar.ts | 78 +++- 9 files changed, 618 insertions(+), 43 deletions(-) create mode 100644 apps/browser/src/autofill/notification/abstractions/notification-bar.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index f8df49c7975..cf0ce679808 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2542,8 +2542,8 @@ "description": "LastPass specific notification button text for cancelling a fileless import." }, "startFilelessImport": { - "message": "Import to Bitwarden", - "description": "Notification button text for starting a fileless import." + "message": "Import to Bitwarden", + "description": "Notification button text for starting a fileless import." }, "importing": { "message": "Importing...", @@ -2993,5 +2993,17 @@ "makeDefault": { "message": "Make default", "description": "Button text for the setting that allows overriding the default browser autofill settings" + }, + "saveCipherAttemptSuccess": { + "message": "Credentials saved successfully!", + "description": "Notification message for when saving credentials has succeeded." + }, + "updateCipherAttemptSuccess": { + "message": "Credentials updated successfully!", + "description": "Notification message for when updating credentials has succeeded." + }, + "saveCipherAttemptFailed": { + "message": "Error saving credentials. Check console for details.", + "description": "Notification message for when saving credentials has failed." } } diff --git a/apps/browser/src/autofill/background/abstractions/notification.background.ts b/apps/browser/src/autofill/background/abstractions/notification.background.ts index 8b7cbf50593..ba6d18edbcb 100644 --- a/apps/browser/src/autofill/background/abstractions/notification.background.ts +++ b/apps/browser/src/autofill/background/abstractions/notification.background.ts @@ -88,6 +88,8 @@ type NotificationBackgroundExtensionMessage = { notificationType?: string; }; +type SaveOrUpdateCipherResult = undefined | { error: string }; + type BackgroundMessageParam = { message: NotificationBackgroundExtensionMessage }; type BackgroundSenderParam = { sender: chrome.runtime.MessageSender }; type BackgroundOnMessageHandlerParams = BackgroundMessageParam & BackgroundSenderParam; @@ -120,6 +122,7 @@ export { ChangePasswordMessageData, UnlockVaultMessageData, AddLoginMessageData, + SaveOrUpdateCipherResult, NotificationBackgroundExtensionMessage, NotificationBackgroundExtensionMessageHandlers, }; diff --git a/apps/browser/src/autofill/background/notification.background.spec.ts b/apps/browser/src/autofill/background/notification.background.spec.ts index 5bee7d40933..af92dae9ebc 100644 --- a/apps/browser/src/autofill/background/notification.background.spec.ts +++ b/apps/browser/src/autofill/background/notification.background.spec.ts @@ -20,6 +20,7 @@ import { createAutofillPageDetailsMock, createChromeTabMock } from "../spec/auto import { flushPromises, sendExtensionRuntimeMessage } from "../spec/testing-utils"; import { + AddChangePasswordQueueMessage, AddLoginQueueMessage, AddUnlockVaultQueueMessage, LockedVaultPendingNotificationsData, @@ -640,6 +641,424 @@ describe("NotificationBackground", () => { }); }); + describe("bgSaveCipher message handler", () => { + let getAuthStatusSpy: jest.SpyInstance; + let tabSendMessageDataSpy: jest.SpyInstance; + let openUnlockPopoutSpy: jest.SpyInstance; + + beforeEach(() => { + getAuthStatusSpy = jest.spyOn(authService, "getAuthStatus"); + tabSendMessageDataSpy = jest.spyOn(BrowserApi, "tabSendMessageData").mockImplementation(); + openUnlockPopoutSpy = jest + .spyOn(notificationBackground as any, "openUnlockPopout") + .mockImplementation(); + }); + + it("skips saving the cipher and opens an unlock popout if the extension is not unlocked", async () => { + const sender = mock({ tab: { id: 1 } }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + getAuthStatusSpy.mockResolvedValueOnce(AuthenticationStatus.Locked); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(getAuthStatusSpy).toHaveBeenCalled(); + expect(tabSendMessageDataSpy).toHaveBeenCalledWith( + sender.tab, + "addToLockedVaultPendingNotifications", + { + commandToRetry: { message, sender }, + target: "notification.background", + }, + ); + expect(openUnlockPopoutSpy).toHaveBeenCalledWith(sender.tab); + }); + + describe("saveOrUpdateCredentials", () => { + let getDecryptedCipherByIdSpy: jest.SpyInstance; + let getAllDecryptedForUrlSpy: jest.SpyInstance; + let updatePasswordSpy: jest.SpyInstance; + let convertAddLoginQueueMessageToCipherViewSpy: jest.SpyInstance; + let tabSendMessageSpy: jest.SpyInstance; + let editItemSpy: jest.SpyInstance; + let setAddEditCipherInfoSpy: jest.SpyInstance; + let openAddEditVaultItemPopoutSpy: jest.SpyInstance; + let createWithServerSpy: jest.SpyInstance; + let updateWithServerSpy: jest.SpyInstance; + let folderExistsSpy: jest.SpyInstance; + let cipherEncryptSpy: jest.SpyInstance; + + beforeEach(() => { + getAuthStatusSpy.mockResolvedValueOnce(AuthenticationStatus.Unlocked); + getDecryptedCipherByIdSpy = jest.spyOn( + notificationBackground as any, + "getDecryptedCipherById", + ); + getAllDecryptedForUrlSpy = jest.spyOn(cipherService, "getAllDecryptedForUrl"); + updatePasswordSpy = jest.spyOn(notificationBackground as any, "updatePassword"); + convertAddLoginQueueMessageToCipherViewSpy = jest.spyOn( + notificationBackground as any, + "convertAddLoginQueueMessageToCipherView", + ); + tabSendMessageSpy = jest.spyOn(BrowserApi, "tabSendMessage").mockImplementation(); + editItemSpy = jest.spyOn(notificationBackground as any, "editItem"); + setAddEditCipherInfoSpy = jest.spyOn(stateService, "setAddEditCipherInfo"); + openAddEditVaultItemPopoutSpy = jest.spyOn( + notificationBackground as any, + "openAddEditVaultItemPopout", + ); + createWithServerSpy = jest.spyOn(cipherService, "createWithServer"); + updateWithServerSpy = jest.spyOn(cipherService, "updateWithServer"); + folderExistsSpy = jest.spyOn(notificationBackground as any, "folderExists"); + cipherEncryptSpy = jest.spyOn(cipherService, "encrypt"); + }); + + it("skips saving the cipher if the notification queue does not have a tab that is related to the sender", async () => { + const sender = mock({ tab: { id: 2 } }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + notificationBackground["notificationQueue"] = [ + mock({ + tab: createChromeTabMock({ id: 1 }), + }), + ]; + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(updatePasswordSpy).not.toHaveBeenCalled(); + expect(editItemSpy).not.toHaveBeenCalled(); + expect(createWithServerSpy).not.toHaveBeenCalled(); + }); + + it("skips saving the cipher if the notification queue does not contain an AddLogin or ChangePassword type", async () => { + const tab = createChromeTabMock({ id: 1 }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + notificationBackground["notificationQueue"] = [ + mock({ + tab, + type: NotificationQueueMessageType.UnlockVault, + }), + ]; + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(updatePasswordSpy).not.toHaveBeenCalled(); + expect(editItemSpy).not.toHaveBeenCalled(); + expect(createWithServerSpy).not.toHaveBeenCalled(); + }); + + it("skips saving the cipher if the notification queue message has a different domain than the passed tab", () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + notificationBackground["notificationQueue"] = [ + mock({ + type: NotificationQueueMessageType.AddLogin, + tab, + domain: "another.com", + }), + ]; + + sendExtensionRuntimeMessage(message, sender); + expect(updatePasswordSpy).not.toHaveBeenCalled(); + expect(editItemSpy).not.toHaveBeenCalled(); + expect(createWithServerSpy).not.toHaveBeenCalled(); + }); + + it("updates the password if the notification message type is for ChangePassword", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.ChangePassword, + tab, + domain: "example.com", + newPassword: "newPassword", + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock(); + getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(editItemSpy).not.toHaveBeenCalled(); + expect(createWithServerSpy).not.toHaveBeenCalled(); + expect(updatePasswordSpy).toHaveBeenCalledWith( + cipherView, + queueMessage.newPassword, + message.edit, + sender.tab, + ); + expect(updateWithServerSpy).toHaveBeenCalled(); + expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { + command: "saveCipherAttemptCompleted", + }); + }); + + it("updates the cipher password if the queue message was locked and an existing cipher has the same username as the message", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.AddLogin, + tab, + domain: "example.com", + username: "test", + password: "updated-password", + wasVaultLocked: true, + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock({ + login: { username: "test", password: "old-password" }, + }); + getAllDecryptedForUrlSpy.mockResolvedValueOnce([cipherView]); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(updatePasswordSpy).toHaveBeenCalledWith( + cipherView, + queueMessage.password, + message.edit, + sender.tab, + ); + expect(editItemSpy).not.toHaveBeenCalled(); + expect(createWithServerSpy).not.toHaveBeenCalled(); + }); + + it("opens an editItem window and closes the notification bar if the edit value is within the passed message when attempting to update an existing cipher", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: true, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.ChangePassword, + tab, + domain: "example.com", + newPassword: "newPassword", + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock(); + getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); + setAddEditCipherInfoSpy.mockResolvedValue(undefined); + openAddEditVaultItemPopoutSpy.mockResolvedValue(undefined); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(updatePasswordSpy).toHaveBeenCalledWith( + cipherView, + queueMessage.newPassword, + message.edit, + sender.tab, + ); + expect(editItemSpy).toHaveBeenCalled(); + expect(updateWithServerSpy).not.toHaveBeenCalled(); + expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { + command: "closeNotificationBar", + }); + expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { + command: "editedCipher", + }); + expect(setAddEditCipherInfoSpy).toHaveBeenCalledWith({ + cipher: cipherView, + collectionIds: cipherView.collectionIds, + }); + expect(openAddEditVaultItemPopoutSpy).toHaveBeenCalledWith(sender.tab, { + cipherId: cipherView.id, + }); + }); + + it("opens an editItem window and closes the notification bar if the edit value is within the passed message when attempting to save the cipher", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: true, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.AddLogin, + tab, + domain: "example.com", + username: "test", + password: "password", + wasVaultLocked: false, + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock({ + login: { username: "test", password: "password" }, + }); + folderExistsSpy.mockResolvedValueOnce(true); + convertAddLoginQueueMessageToCipherViewSpy.mockReturnValueOnce(cipherView); + editItemSpy.mockResolvedValueOnce(undefined); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(updatePasswordSpy).not.toHaveBeenCalled(); + expect(convertAddLoginQueueMessageToCipherViewSpy).toHaveBeenCalledWith( + queueMessage, + message.folder, + ); + expect(editItemSpy).toHaveBeenCalledWith(cipherView, sender.tab); + expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { + command: "closeNotificationBar", + }); + expect(createWithServerSpy).not.toHaveBeenCalled(); + }); + + it("creates the cipher within the server and sends an `saveCipherAttemptCompleted` and `addedCipher` message to the sender tab", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.AddLogin, + tab, + domain: "example.com", + username: "test", + password: "password", + wasVaultLocked: false, + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock({ + login: { username: "test", password: "password" }, + }); + folderExistsSpy.mockResolvedValueOnce(false); + convertAddLoginQueueMessageToCipherViewSpy.mockReturnValueOnce(cipherView); + editItemSpy.mockResolvedValueOnce(undefined); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(convertAddLoginQueueMessageToCipherViewSpy).toHaveBeenCalledWith( + queueMessage, + null, + ); + expect(cipherEncryptSpy).toHaveBeenCalledWith(cipherView); + expect(createWithServerSpy).toHaveBeenCalled(); + expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { + command: "saveCipherAttemptCompleted", + }); + expect(tabSendMessageSpy).toHaveBeenCalledWith(sender.tab, { command: "addedCipher" }); + }); + + it("sends an error message within the `saveCipherAttemptCompleted` message if the cipher cannot be saved to the server", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.AddLogin, + tab, + domain: "example.com", + username: "test", + password: "password", + wasVaultLocked: false, + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock({ + login: { username: "test", password: "password" }, + }); + folderExistsSpy.mockResolvedValueOnce(true); + convertAddLoginQueueMessageToCipherViewSpy.mockReturnValueOnce(cipherView); + editItemSpy.mockResolvedValueOnce(undefined); + const errorMessage = "fetch error"; + createWithServerSpy.mockImplementation(() => { + throw new Error(errorMessage); + }); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(cipherEncryptSpy).toHaveBeenCalledWith(cipherView); + expect(createWithServerSpy).toThrow(errorMessage); + expect(tabSendMessageSpy).not.toHaveBeenCalledWith(sender.tab, { + command: "addedCipher", + }); + expect(tabSendMessageDataSpy).toHaveBeenCalledWith( + sender.tab, + "saveCipherAttemptCompleted", + { + error: errorMessage, + }, + ); + }); + + it("sends an error message within the `saveCipherAttemptCompleted` message if the cipher cannot be updated within the server", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.ChangePassword, + tab, + domain: "example.com", + newPassword: "newPassword", + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock(); + getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); + const errorMessage = "fetch error"; + updateWithServerSpy.mockImplementation(() => { + throw new Error(errorMessage); + }); + + sendExtensionRuntimeMessage(message, sender); + await flushPromises(); + + expect(updateWithServerSpy).toThrow(errorMessage); + expect(tabSendMessageDataSpy).toHaveBeenCalledWith( + sender.tab, + "saveCipherAttemptCompleted", + { + error: errorMessage, + }, + ); + }); + }); + }); + describe("bgNeverSave message handler", () => { let tabSendMessageDataSpy: jest.SpyInstance; diff --git a/apps/browser/src/autofill/background/notification.background.ts b/apps/browser/src/autofill/background/notification.background.ts index cb49e47eb64..42d8d47b23e 100644 --- a/apps/browser/src/autofill/background/notification.background.ts +++ b/apps/browser/src/autofill/background/notification.background.ts @@ -39,6 +39,7 @@ import { OverlayBackgroundExtensionMessage } from "./abstractions/overlay.backgr export default class NotificationBackground { private openUnlockPopout = openUnlockPopout; + private openAddEditVaultItemPopout = openAddEditVaultItemPopout; private notificationQueue: NotificationQueueMessageItem[] = []; private readonly extensionMessageHandlers: NotificationBackgroundExtensionMessageHandlers = { unlockCompleted: ({ message, sender }) => this.handleUnlockCompleted(message, sender), @@ -431,6 +432,14 @@ export default class NotificationBackground { this.removeTabFromNotificationQueue(tab); } + /** + * Saves a cipher based on the message sent from the notification bar. If the vault + * is locked, the message will be added to the notification queue and the unlock + * popout will be opened. + * + * @param message - The extension message + * @param sender - The contextual sender of the message + */ private async handleSaveCipherMessage( message: NotificationBackgroundExtensionMessage, sender: chrome.runtime.MessageSender, @@ -454,6 +463,14 @@ export default class NotificationBackground { await this.saveOrUpdateCredentials(sender.tab, message.edit, message.folder); } + /** + * Saves or updates credentials based on the message within the + * notification queue that is associated with the specified tab. + * + * @param tab - The tab to save or update credentials for + * @param edit - Identifies if the credentials should be edited or simply added + * @param folderId - The folder to add the cipher to + */ private async saveOrUpdateCredentials(tab: chrome.tabs.Tab, edit: boolean, folderId?: string) { for (let i = this.notificationQueue.length - 1; i >= 0; i--) { const queueMessage = this.notificationQueue[i]; @@ -471,9 +488,6 @@ export default class NotificationBackground { } this.notificationQueue.splice(i, 1); - BrowserApi.tabSendMessageData(tab, "closeNotificationBar").catch((error) => - this.logService.error(error), - ); if (queueMessage.type === NotificationQueueMessageType.ChangePassword) { const cipherView = await this.getDecryptedCipherById(queueMessage.cipherId); @@ -481,38 +495,52 @@ export default class NotificationBackground { return; } - if (queueMessage.type === NotificationQueueMessageType.AddLogin) { - // If the vault was locked, check if a cipher needs updating instead of creating a new one - if (queueMessage.wasVaultLocked) { - const allCiphers = await this.cipherService.getAllDecryptedForUrl(queueMessage.uri); - const existingCipher = allCiphers.find( - (c) => - c.login.username != null && c.login.username.toLowerCase() === queueMessage.username, - ); + // If the vault was locked, check if a cipher needs updating instead of creating a new one + if (queueMessage.wasVaultLocked) { + const allCiphers = await this.cipherService.getAllDecryptedForUrl(queueMessage.uri); + const existingCipher = allCiphers.find( + (c) => + c.login.username != null && c.login.username.toLowerCase() === queueMessage.username, + ); - if (existingCipher != null) { - await this.updatePassword(existingCipher, queueMessage.password, edit, tab); - return; - } - } - - folderId = (await this.folderExists(folderId)) ? folderId : null; - const newCipher = this.convertAddLoginQueueMessageToCipherView(queueMessage, folderId); - - if (edit) { - await this.editItem(newCipher, tab); + if (existingCipher != null) { + await this.updatePassword(existingCipher, queueMessage.password, edit, tab); return; } + } - const cipher = await this.cipherService.encrypt(newCipher); + folderId = (await this.folderExists(folderId)) ? folderId : null; + const newCipher = this.convertAddLoginQueueMessageToCipherView(queueMessage, folderId); + + if (edit) { + await this.editItem(newCipher, tab); + await BrowserApi.tabSendMessage(tab, { command: "closeNotificationBar" }); + return; + } + + const cipher = await this.cipherService.encrypt(newCipher); + try { await this.cipherService.createWithServer(cipher); - BrowserApi.tabSendMessageData(tab, "addedCipher").catch((error) => - this.logService.error(error), - ); + await BrowserApi.tabSendMessage(tab, { command: "saveCipherAttemptCompleted" }); + await BrowserApi.tabSendMessage(tab, { command: "addedCipher" }); + } catch (error) { + await BrowserApi.tabSendMessageData(tab, "saveCipherAttemptCompleted", { + error: String(error.message), + }); } } } + /** + * Handles updating an existing cipher's password. If the cipher + * is being edited, a popup will be opened to allow the user to + * edit the cipher. + * + * @param cipherView - The cipher to update + * @param newPassword - The new password to update the cipher with + * @param edit - Identifies if the cipher should be edited or simply updated + * @param tab - The tab that the message was sent from + */ private async updatePassword( cipherView: CipherView, newPassword: string, @@ -523,23 +551,37 @@ export default class NotificationBackground { if (edit) { await this.editItem(cipherView, tab); + await BrowserApi.tabSendMessage(tab, { command: "closeNotificationBar" }); await BrowserApi.tabSendMessage(tab, { command: "editedCipher" }); return; } const cipher = await this.cipherService.encrypt(cipherView); - await this.cipherService.updateWithServer(cipher); - // We've only updated the password, no need to broadcast editedCipher message - return; + try { + // We've only updated the password, no need to broadcast editedCipher message + await this.cipherService.updateWithServer(cipher); + await BrowserApi.tabSendMessage(tab, { command: "saveCipherAttemptCompleted" }); + } catch (error) { + await BrowserApi.tabSendMessageData(tab, "saveCipherAttemptCompleted", { + error: String(error.message), + }); + } } + /** + * Sets the add/edit cipher info in the state service + * and opens the add/edit vault item popout. + * + * @param cipherView - The cipher to edit + * @param senderTab - The tab that the message was sent from + */ private async editItem(cipherView: CipherView, senderTab: chrome.tabs.Tab) { await this.stateService.setAddEditCipherInfo({ cipher: cipherView, collectionIds: cipherView.collectionIds, }); - await openAddEditVaultItemPopout(senderTab, { cipherId: cipherView.id }); + await this.openAddEditVaultItemPopout(senderTab, { cipherId: cipherView.id }); } private async folderExists(folderId: string) { diff --git a/apps/browser/src/autofill/content/notification-bar.ts b/apps/browser/src/autofill/content/notification-bar.ts index 175f5ada2cd..ac20401da58 100644 --- a/apps/browser/src/autofill/content/notification-bar.ts +++ b/apps/browser/src/autofill/content/notification-bar.ts @@ -194,6 +194,18 @@ async function loadNotificationBar() { watchForms(msg.data.forms); sendResponse(); return true; + } else if (msg.command === "saveCipherAttemptCompleted") { + if (!notificationBarIframe) { + return; + } + + notificationBarIframe.contentWindow?.postMessage( + { + command: "saveCipherAttemptCompleted", + error: msg.data?.error, + }, + "*", + ); } } // End Message Processing diff --git a/apps/browser/src/autofill/notification/abstractions/notification-bar.ts b/apps/browser/src/autofill/notification/abstractions/notification-bar.ts new file mode 100644 index 00000000000..e2753893b1d --- /dev/null +++ b/apps/browser/src/autofill/notification/abstractions/notification-bar.ts @@ -0,0 +1,13 @@ +import { SaveOrUpdateCipherResult } from "../../background/abstractions/notification.background"; + +type NotificationBarWindowMessage = { + [key: string]: any; + command: string; +}; + +type NotificationBarWindowMessageHandlers = { + [key: string]: CallableFunction; + saveCipherAttemptCompleted: ({ message }: { message: SaveOrUpdateCipherResult }) => void; +}; + +export { NotificationBarWindowMessage, NotificationBarWindowMessageHandlers }; diff --git a/apps/browser/src/autofill/notification/bar.html b/apps/browser/src/autofill/notification/bar.html index 057e4273bc7..26d9d7086d4 100644 --- a/apps/browser/src/autofill/notification/bar.html +++ b/apps/browser/src/autofill/notification/bar.html @@ -6,7 +6,7 @@ -