diff --git a/README.md b/README.md index d76e58db..189d3ab0 100644 --- a/README.md +++ b/README.md @@ -22,22 +22,11 @@ The Bitwarden desktop app is written using Electron and Angular. The application - [Node.js](https://nodejs.org) v16.13.1 (LTS) or greater - NPM v8 -- Rust (https://www.rust-lang.org/tools/install) - Windows: - To compile the native node modules used in the app you will need the _Visual C++ toolset_, available through the standard Visual Studio installer. You will also need to install the _Microsoft Build Tools 2015_ and _Windows 10 SDK 17134_ as additional dependencies in the Visual Studio installer. - Linux: - The following packages `build-essential libsecret-1-dev libglib2.0-dev` -## Build native module - -The desktop application relies on native code written in rust, which needs to be compiled first. - -```bash -cd desktop_native -npm ci -npm run build -``` - ## Run the app ```bash diff --git a/jslib b/jslib index 6bcadc4f..c757cc7a 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 6bcadc4f408db2c150753f53a07d6f8888b6e9ff +Subproject commit c757cc7ab68d3e1f63b7a00ad50a7076a3248d87 diff --git a/package-lock.json b/package-lock.json index fe7887aa..44b5babf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,12 +19,12 @@ "@angular/platform-browser": "^12.2.13", "@angular/platform-browser-dynamic": "^12.2.13", "@angular/router": "^12.2.13", - "@bitwarden/desktop-native": "file:desktop_native", "@bitwarden/jslib-angular": "file:jslib/angular", "@bitwarden/jslib-common": "file:jslib/common", "@bitwarden/jslib-electron": "file:jslib/electron", "@nodert-win10-rs4/windows.security.credentials.ui": "^0.4.4", "forcefocus": "^1.1.0", + "keytar": "^7.9.0", "ngx-toastr": "14.1.4", "node-ipc": "^9.1.4", "nord": "^0.2.1", @@ -79,11 +79,10 @@ "desktop_native": { "name": "@bitwarden/desktop_native", "version": "0.1.0", - "hasInstallScript": true, + "extraneous": true, "license": "GPL-3.0", "devDependencies": { - "@napi-rs/cli": "^2.4.4", - "cargo-cp-artifact": "^0.1" + "@napi-rs/cli": "^2.6.2" } }, "jslib/angular": { @@ -654,10 +653,6 @@ "node": ">=6.9.0" } }, - "node_modules/@bitwarden/desktop-native": { - "resolved": "desktop_native", - "link": true - }, "node_modules/@bitwarden/jslib-angular": { "resolved": "jslib/angular", "link": true @@ -1093,22 +1088,6 @@ "msgpack5": "^4.5.0" } }, - "node_modules/@napi-rs/cli": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.6.2.tgz", - "integrity": "sha512-EmH+DQDEBUIoqMim0cc+X96ImtcIZLFjgW5WWORpzYnA9Ug7zNPO7jCLMhIQRd/p5AdWaXrT4SVXc/aip09rKQ==", - "dev": true, - "bin": { - "napi": "scripts/index.js" - }, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - } - }, "node_modules/@ngtools/webpack": { "version": "12.2.17", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.2.17.tgz", @@ -2193,9 +2172,9 @@ } }, "node_modules/async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, "node_modules/async-exit-hook": { @@ -2772,15 +2751,6 @@ "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", "dev": true }, - "node_modules/cargo-cp-artifact": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/cargo-cp-artifact/-/cargo-cp-artifact-0.1.6.tgz", - "integrity": "sha512-CQw0doK/aaF7j041666XzuilHxqMxaKkn+I5vmBsd8SAwS0cO5CqVEVp0xJwOKstyqWZ6WK4Ww3O6p26x/Goyg==", - "dev": true, - "bin": { - "cargo-cp-artifact": "bin/cargo-cp-artifact.js" - } - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -3600,7 +3570,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, "dependencies": { "mimic-response": "^3.1.0" }, @@ -3615,7 +3584,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -4020,12 +3988,12 @@ } }, "node_modules/ejs": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", - "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz", + "integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==", "dev": true, "dependencies": { - "jake": "^10.6.1" + "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" @@ -5303,12 +5271,33 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "node_modules/filelist": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", - "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.3.tgz", + "integrity": "sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q==", "dev": true, "dependencies": { - "minimatch": "^3.0.4" + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, "node_modules/fill-range": { @@ -6563,12 +6552,12 @@ } }, "node_modules/jake": { - "version": "10.8.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.4.tgz", - "integrity": "sha512-MtWeTkl1qGsWUtbl/Jsca/8xSoK3x0UmS82sNbjqxxG/de/M/3b1DntdjHgPMC50enlTNwXOCRqPXLLt5cCfZA==", + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", "dev": true, "dependencies": { - "async": "0.9.x", + "async": "^3.2.3", "chalk": "^4.0.2", "filelist": "^1.0.1", "minimatch": "^3.0.4" @@ -6794,6 +6783,184 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "node_modules/keytar/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/keytar/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "node_modules/keytar/node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/keytar/node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/keytar/node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/keytar/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/keytar/node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "node_modules/keytar/node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/keytar/node_modules/prebuild-install": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.0.tgz", + "integrity": "sha512-CNcMgI1xBypOyGqjp3wOc8AAo1nMhZS3Cwd3iHIxOdAUbb+YxdNuM4Z5iIrZ8RLvOsf3F3bl7b7xGq6DjQoNYA==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/keytar/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/keytar/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/keytar/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/keytar/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/keytar/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/keyv": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", @@ -7766,7 +7933,6 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", - "dev": true, "dependencies": { "semver": "^7.3.5" }, @@ -11753,13 +11919,6 @@ "to-fast-properties": "^2.0.0" } }, - "@bitwarden/desktop-native": { - "version": "file:desktop_native", - "requires": { - "@napi-rs/cli": "^2.4.4", - "cargo-cp-artifact": "^0.1" - } - }, "@bitwarden/jslib-angular": { "version": "file:jslib/angular", "requires": { @@ -12153,12 +12312,6 @@ "msgpack5": "^4.5.0" } }, - "@napi-rs/cli": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.6.2.tgz", - "integrity": "sha512-EmH+DQDEBUIoqMim0cc+X96ImtcIZLFjgW5WWORpzYnA9Ug7zNPO7jCLMhIQRd/p5AdWaXrT4SVXc/aip09rKQ==", - "dev": true - }, "@ngtools/webpack": { "version": "12.2.17", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.2.17.tgz", @@ -13016,9 +13169,9 @@ "dev": true }, "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, "async-exit-hook": { @@ -13436,12 +13589,6 @@ "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", "dev": true }, - "cargo-cp-artifact": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/cargo-cp-artifact/-/cargo-cp-artifact-0.1.6.tgz", - "integrity": "sha512-CQw0doK/aaF7j041666XzuilHxqMxaKkn+I5vmBsd8SAwS0cO5CqVEVp0xJwOKstyqWZ6WK4Ww3O6p26x/Goyg==", - "dev": true - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -14040,7 +14187,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, "requires": { "mimic-response": "^3.1.0" }, @@ -14048,8 +14194,7 @@ "mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" } } }, @@ -14364,12 +14509,12 @@ "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==" }, "ejs": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", - "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz", + "integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==", "dev": true, "requires": { - "jake": "^10.6.1" + "jake": "^10.8.5" } }, "electron": { @@ -15354,12 +15499,32 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "filelist": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", - "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.3.tgz", + "integrity": "sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q==", "dev": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "fill-range": { @@ -16246,12 +16411,12 @@ "dev": true }, "jake": { - "version": "10.8.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.4.tgz", - "integrity": "sha512-MtWeTkl1qGsWUtbl/Jsca/8xSoK3x0UmS82sNbjqxxG/de/M/3b1DntdjHgPMC50enlTNwXOCRqPXLLt5cCfZA==", + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", "dev": true, "requires": { - "async": "0.9.x", + "async": "^3.2.3", "chalk": "^4.0.2", "filelist": "^1.0.1", "minimatch": "^3.0.4" @@ -16419,6 +16584,150 @@ "universalify": "^2.0.0" } }, + "keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "requires": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "prebuild-install": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.0.tgz", + "integrity": "sha512-CNcMgI1xBypOyGqjp3wOc8AAo1nMhZS3Cwd3iHIxOdAUbb+YxdNuM4Z5iIrZ8RLvOsf3F3bl7b7xGq6DjQoNYA==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "keyv": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", @@ -17141,7 +17450,6 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", - "dev": true, "requires": { "semver": "^7.3.5" } diff --git a/package.json b/package.json index f735bd60..98506d67 100644 --- a/package.json +++ b/package.json @@ -111,12 +111,12 @@ "@angular/platform-browser": "^12.2.13", "@angular/platform-browser-dynamic": "^12.2.13", "@angular/router": "^12.2.13", - "@bitwarden/desktop-native": "file:desktop_native", "@bitwarden/jslib-angular": "file:jslib/angular", "@bitwarden/jslib-common": "file:jslib/common", "@bitwarden/jslib-electron": "file:jslib/electron", "@nodert-win10-rs4/windows.security.credentials.ui": "^0.4.4", "forcefocus": "^1.1.0", + "keytar": "^7.9.0", "ngx-toastr": "14.1.4", "node-ipc": "^9.1.4", "nord": "^0.2.1", diff --git a/src/app/accounts/hint.component.html b/src/app/accounts/hint.component.html index 19ce6e77..55137081 100644 --- a/src/app/accounts/hint.component.html +++ b/src/app/accounts/hint.component.html @@ -25,7 +25,7 @@ {{ "submit" | i18n }} - {{ "cancel" | i18n }} + {{ "cancel" | i18n }} diff --git a/src/app/accounts/lock.component.html b/src/app/accounts/lock.component.html index e503282c..71ac7594 100644 --- a/src/app/accounts/lock.component.html +++ b/src/app/accounts/lock.component.html @@ -30,12 +30,11 @@ />
- +
diff --git a/src/app/accounts/login.component.html b/src/app/accounts/login.component.html index d4495781..bf7830e1 100644 --- a/src/app/accounts/login.component.html +++ b/src/app/accounts/login.component.html @@ -1,7 +1,7 @@
- {{ "settings" | i18n }} - +
- +
@@ -83,18 +82,22 @@ > - + {{ "createAccount" | i18n }}
- +
- {{ "getMasterPasswordHint" | i18n }} + {{ "getMasterPasswordHint" | i18n }}
diff --git a/src/app/accounts/register.component.html b/src/app/accounts/register.component.html index c0c3ce14..4136f5cf 100644 --- a/src/app/accounts/register.component.html +++ b/src/app/accounts/register.component.html @@ -40,12 +40,11 @@ />
- +
@@ -91,12 +90,11 @@ />
- +
@@ -146,7 +144,7 @@ {{ "submit" | i18n }} - {{ "cancel" | i18n }} + {{ "cancel" | i18n }}
diff --git a/src/app/accounts/set-password.component.html b/src/app/accounts/set-password.component.html index d7afcda8..61e99105 100644 --- a/src/app/accounts/set-password.component.html +++ b/src/app/accounts/set-password.component.html @@ -56,12 +56,11 @@ />
- +
@@ -109,12 +108,11 @@ />
- +
diff --git a/src/app/accounts/two-factor-options.component.html b/src/app/accounts/two-factor-options.component.html index 8dd875e9..778d2636 100644 --- a/src/app/accounts/two-factor-options.component.html +++ b/src/app/accounts/two-factor-options.component.html @@ -7,8 +7,8 @@ {{ "twoStepOptions" | i18n }}
- {{ p.name }} {{ p.description }} - - + +
diff --git a/src/app/accounts/two-factor.component.html b/src/app/accounts/two-factor.component.html index aab55ab2..e2abd0f8 100644 --- a/src/app/accounts/two-factor.component.html +++ b/src/app/accounts/two-factor.component.html @@ -124,22 +124,21 @@ > - {{ "cancel" | i18n }} + {{ "cancel" | i18n }}
- {{ - "useAnotherTwoStepMethod" | i18n - }} - + {{ "useAnotherTwoStepMethod" | i18n }} + +
diff --git a/src/app/accounts/two-factor.component.ts b/src/app/accounts/two-factor.component.ts index db482230..acf8919f 100644 --- a/src/app/accounts/two-factor.component.ts +++ b/src/app/accounts/two-factor.component.ts @@ -4,6 +4,7 @@ import { ActivatedRoute, Router } from "@angular/router"; import { TwoFactorComponent as BaseTwoFactorComponent } from "jslib-angular/components/two-factor.component"; import { ModalService } from "jslib-angular/services/modal.service"; import { ApiService } from "jslib-common/abstractions/api.service"; +import { AppIdService } from "jslib-common/abstractions/appId.service"; import { AuthService } from "jslib-common/abstractions/auth.service"; import { EnvironmentService } from "jslib-common/abstractions/environment.service"; import { I18nService } from "jslib-common/abstractions/i18n.service"; @@ -38,7 +39,8 @@ export class TwoFactorComponent extends BaseTwoFactorComponent { stateService: StateService, route: ActivatedRoute, logService: LogService, - twoFactorService: TwoFactorService + twoFactorService: TwoFactorService, + appIdService: AppIdService ) { super( authService, @@ -51,7 +53,8 @@ export class TwoFactorComponent extends BaseTwoFactorComponent { stateService, route, logService, - twoFactorService + twoFactorService, + appIdService ); super.onSuccessfulLogin = () => { return syncService.fullSync(true); diff --git a/src/app/accounts/update-temp-password.component.html b/src/app/accounts/update-temp-password.component.html index 26ee4672..084c3217 100644 --- a/src/app/accounts/update-temp-password.component.html +++ b/src/app/accounts/update-temp-password.component.html @@ -36,12 +36,11 @@ />
- +
@@ -84,12 +83,11 @@ />
- +
@@ -120,7 +118,7 @@ {{ "submit" | i18n }} - {{ "logOut" | i18n }} + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8923eb45..b824b5fe 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -35,6 +35,7 @@ import { SyncService } from "jslib-common/abstractions/sync.service"; import { SystemService } from "jslib-common/abstractions/system.service"; import { TokenService } from "jslib-common/abstractions/token.service"; import { VaultTimeoutService } from "jslib-common/abstractions/vaultTimeout.service"; +import { AuthenticationStatus } from "jslib-common/enums/authenticationStatus"; import { CipherType } from "jslib-common/enums/cipherType"; import { MenuUpdateRequest } from "../main/menu/menu.updater"; @@ -330,7 +331,9 @@ export class AppComponent implements OnInit { if (message.userId != null) { await this.stateService.setActiveUser(message.userId); } - const locked = await this.vaultTimeoutService.isLocked(message.userId); + const locked = + (await this.authService.getAuthStatus(message.userId)) === + AuthenticationStatus.Locked; if (locked) { this.messagingService.send("locked", { userId: message.userId }); } else { @@ -436,7 +439,8 @@ export class AppComponent implements OnInit { isAuthenticated: await this.stateService.getIsAuthenticated({ userId: userId, }), - isLocked: await this.vaultTimeoutService.isLocked(userId), + isLocked: + (await this.authService.getAuthStatus(userId)) === AuthenticationStatus.Locked, email: stateAccounts[i].profile.email, userId: stateAccounts[i].profile.userId, }; @@ -591,7 +595,7 @@ export class AppComponent implements OnInit { const keys = Object.keys(accounts); if (keys.length > 0) { for (const userId of keys) { - if (!(await this.vaultTimeoutService.isLocked(userId))) { + if ((await this.authService.getAuthStatus(userId)) === AuthenticationStatus.Unlocked) { return; } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3cd8197d..29e324cf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -91,7 +91,7 @@ import { SearchComponent } from "./layout/search/search.component"; import { AddEditComponent as SendAddEditComponent } from "./send/add-edit.component"; import { EffluxDatesComponent as SendEffluxDatesComponent } from "./send/efflux-dates.component"; import { SendComponent } from "./send/send.component"; -import { ServicesModule } from "./services.module"; +import { ServicesModule } from "./services/services.module"; import { AddEditCustomFieldsComponent } from "./vault/add-edit-custom-fields.component"; import { AddEditComponent } from "./vault/add-edit.component"; import { AttachmentsComponent } from "./vault/attachments.component"; diff --git a/src/app/components/password-reprompt.component.html b/src/app/components/password-reprompt.component.html index f2805761..078e983b 100644 --- a/src/app/components/password-reprompt.component.html +++ b/src/app/components/password-reprompt.component.html @@ -19,12 +19,11 @@ />
- +
diff --git a/src/app/components/set-pin.component.html b/src/app/components/set-pin.component.html index 538eb0a2..78552942 100644 --- a/src/app/components/set-pin.component.html +++ b/src/app/components/set-pin.component.html @@ -22,9 +22,9 @@ />
- +
diff --git a/src/app/layout/account-switcher.component.html b/src/app/layout/account-switcher.component.html index a01907f1..0d52b719 100644 --- a/src/app/layout/account-switcher.component.html +++ b/src/app/layout/account-switcher.component.html @@ -53,7 +53,6 @@ diff --git a/src/app/layout/account-switcher.component.ts b/src/app/layout/account-switcher.component.ts index 6fb6c140..1958bed7 100644 --- a/src/app/layout/account-switcher.component.ts +++ b/src/app/layout/account-switcher.component.ts @@ -2,9 +2,9 @@ import { animate, state, style, transition, trigger } from "@angular/animations" import { ConnectedPosition } from "@angular/cdk/overlay"; import { Component, OnInit } from "@angular/core"; +import { AuthService } from "jslib-common/abstractions/auth.service"; import { MessagingService } from "jslib-common/abstractions/messaging.service"; import { StateService } from "jslib-common/abstractions/state.service"; -import { VaultTimeoutService } from "jslib-common/abstractions/vaultTimeout.service"; import { AuthenticationStatus } from "jslib-common/enums/authenticationStatus"; import { Utils } from "jslib-common/misc/utils"; import { Account } from "jslib-common/models/domain/account"; @@ -53,6 +53,7 @@ export class AccountSwitcherComponent implements OnInit { accounts: { [userId: string]: SwitcherAccount } = {}; activeAccountEmail: string; serverUrl: string; + authStatus = AuthenticationStatus; overlayPostition: ConnectedPosition[] = [ { originX: "end", @@ -78,22 +79,16 @@ export class AccountSwitcherComponent implements OnInit { constructor( private stateService: StateService, - private vaultTimeoutService: VaultTimeoutService, + private authService: AuthService, private messagingService: MessagingService ) {} async ngOnInit(): Promise { - this.stateService.accounts.subscribe(async (accounts) => { + this.stateService.accounts.subscribe(async (accounts: { [userId: string]: Account }) => { for (const userId in accounts) { - if (userId === (await this.stateService.getUserId())) { - accounts[userId].profile.authenticationStatus = AuthenticationStatus.Active; - } else { - accounts[userId].profile.authenticationStatus = (await this.vaultTimeoutService.isLocked( - userId - )) - ? AuthenticationStatus.Locked - : AuthenticationStatus.Unlocked; - } + accounts[userId].profile.authenticationStatus = await this.authService.getAuthStatus( + userId + ); } this.accounts = await this.createSwitcherAccounts(accounts); diff --git a/src/app/send/add-edit.component.html b/src/app/send/add-edit.component.html index 7a43aacb..a91bfb6c 100644 --- a/src/app/send/add-edit.component.html +++ b/src/app/send/add-edit.component.html @@ -93,21 +93,21 @@
- {{ "options" | i18n }} - + {{ "options" | i18n }} - +
@@ -157,12 +157,11 @@ />
- +
diff --git a/src/app/send/send.component.html b/src/app/send/send.component.html index fc52a836..853debb5 100644 --- a/src/app/send/send.component.html +++ b/src/app/send/send.component.html @@ -5,26 +5,44 @@

{{ "filters" | i18n }}

{{ "types" | i18n }}

@@ -36,20 +54,21 @@
diff --git a/src/app/services.module.ts b/src/app/services.module.ts deleted file mode 100644 index 74acaabc..00000000 --- a/src/app/services.module.ts +++ /dev/null @@ -1,211 +0,0 @@ -import { APP_INITIALIZER, NgModule } from "@angular/core"; - -import { JslibServicesModule } from "jslib-angular/services/jslib-services.module"; -import { BroadcasterService as BroadcasterServiceAbstraction } from "jslib-common/abstractions/broadcaster.service"; -import { CryptoService as CryptoServiceAbstraction } from "jslib-common/abstractions/crypto.service"; -import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "jslib-common/abstractions/cryptoFunction.service"; -import { EnvironmentService as EnvironmentServiceAbstraction } from "jslib-common/abstractions/environment.service"; -import { EventService as EventServiceAbstraction } from "jslib-common/abstractions/event.service"; -import { I18nService as I18nServiceAbstraction } from "jslib-common/abstractions/i18n.service"; -import { LogService as LogServiceAbstraction } from "jslib-common/abstractions/log.service"; -import { MessagingService as MessagingServiceAbstraction } from "jslib-common/abstractions/messaging.service"; -import { NotificationsService as NotificationsServiceAbstraction } from "jslib-common/abstractions/notifications.service"; -import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "jslib-common/abstractions/passwordReprompt.service"; -import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "jslib-common/abstractions/platformUtils.service"; -import { StateService as StateServiceAbstraction } from "jslib-common/abstractions/state.service"; -import { StateMigrationService as StateMigrationServiceAbstraction } from "jslib-common/abstractions/stateMigration.service"; -import { StorageService as StorageServiceAbstraction } from "jslib-common/abstractions/storage.service"; -import { SyncService as SyncServiceAbstraction } from "jslib-common/abstractions/sync.service"; -import { SystemService as SystemServiceAbstraction } from "jslib-common/abstractions/system.service"; -import { TwoFactorService as TwoFactorServiceAbstraction } from "jslib-common/abstractions/twoFactor.service"; -import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "jslib-common/abstractions/vaultTimeout.service"; -import { ThemeType } from "jslib-common/enums/themeType"; -import { StateFactory } from "jslib-common/factories/stateFactory"; -import { GlobalState } from "jslib-common/models/domain/globalState"; -import { ContainerService } from "jslib-common/services/container.service"; -import { EventService } from "jslib-common/services/event.service"; -import { StateMigrationService } from "jslib-common/services/stateMigration.service"; -import { SystemService } from "jslib-common/services/system.service"; -import { VaultTimeoutService } from "jslib-common/services/vaultTimeout.service"; -import { ElectronCryptoService } from "jslib-electron/services/electronCrypto.service"; -import { ElectronLogService } from "jslib-electron/services/electronLog.service"; -import { ElectronPlatformUtilsService } from "jslib-electron/services/electronPlatformUtils.service"; -import { ElectronRendererMessagingService } from "jslib-electron/services/electronRendererMessaging.service"; -import { ElectronRendererSecureStorageService } from "jslib-electron/services/electronRendererSecureStorage.service"; -import { ElectronRendererStorageService } from "jslib-electron/services/electronRendererStorage.service"; - -import { Account } from "../models/account"; -import { I18nService } from "../services/i18n.service"; -import { LoginGuardService } from "../services/loginGuard.service"; -import { NativeMessagingService } from "../services/nativeMessaging.service"; -import { PasswordRepromptService } from "../services/passwordReprompt.service"; -import { StateService } from "../services/state.service"; - -import { SearchBarService } from "./layout/search/search-bar.service"; - -export function initFactory( - window: Window, - environmentService: EnvironmentServiceAbstraction, - syncService: SyncServiceAbstraction, - vaultTimeoutService: VaultTimeoutService, - i18nService: I18nService, - eventService: EventService, - twoFactorService: TwoFactorServiceAbstraction, - notificationsService: NotificationsServiceAbstraction, - platformUtilsService: PlatformUtilsServiceAbstraction, - stateService: StateServiceAbstraction, - cryptoService: CryptoServiceAbstraction, - nativeMessagingService: NativeMessagingService -): () => Promise { - return async () => { - nativeMessagingService.init(); - await stateService.init(); - await environmentService.setUrlsFromStorage(); - syncService.fullSync(true); - await vaultTimeoutService.init(true); - const locale = await stateService.getLocale(); - await i18nService.init(locale); - eventService.init(true); - twoFactorService.init(); - setTimeout(() => notificationsService.init(), 3000); - const htmlEl = window.document.documentElement; - htmlEl.classList.add("os_" + platformUtilsService.getDeviceString()); - htmlEl.classList.add("locale_" + i18nService.translationLocale); - const theme = await platformUtilsService.getEffectiveTheme(); - htmlEl.classList.add("theme_" + theme); - platformUtilsService.onDefaultSystemThemeChange(async (sysTheme) => { - const bwTheme = await stateService.getTheme(); - if (bwTheme == null || bwTheme === ThemeType.System) { - htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark); - htmlEl.classList.add("theme_" + sysTheme); - } - }); - - let installAction = null; - const installedVersion = await stateService.getInstalledVersion(); - const currentVersion = await platformUtilsService.getApplicationVersion(); - if (installedVersion == null) { - installAction = "install"; - } else if (installedVersion !== currentVersion) { - installAction = "update"; - } - - if (installAction != null) { - await stateService.setInstalledVersion(currentVersion); - } - - const containerService = new ContainerService(cryptoService); - containerService.attachToGlobal(window); - }; -} - -@NgModule({ - imports: [JslibServicesModule], - declarations: [], - providers: [ - { - provide: APP_INITIALIZER, - useFactory: initFactory, - deps: [ - "WINDOW", - EnvironmentServiceAbstraction, - SyncServiceAbstraction, - VaultTimeoutServiceAbstraction, - I18nServiceAbstraction, - EventServiceAbstraction, - TwoFactorServiceAbstraction, - NotificationsServiceAbstraction, - PlatformUtilsServiceAbstraction, - StateServiceAbstraction, - CryptoServiceAbstraction, - NativeMessagingService, - ], - multi: true, - }, - { provide: LogServiceAbstraction, useClass: ElectronLogService, deps: [] }, - { - provide: PlatformUtilsServiceAbstraction, - useFactory: ( - i18nService: I18nServiceAbstraction, - messagingService: MessagingServiceAbstraction, - stateService: StateServiceAbstraction - ) => new ElectronPlatformUtilsService(i18nService, messagingService, true, stateService), - deps: [I18nServiceAbstraction, MessagingServiceAbstraction, StateServiceAbstraction], - }, - { - provide: I18nServiceAbstraction, - useFactory: (window: Window) => new I18nService(window.navigator.language, "./locales"), - deps: ["WINDOW"], - }, - { - provide: MessagingServiceAbstraction, - useClass: ElectronRendererMessagingService, - deps: [BroadcasterServiceAbstraction], - }, - { provide: StorageServiceAbstraction, useClass: ElectronRendererStorageService }, - { provide: "SECURE_STORAGE", useClass: ElectronRendererSecureStorageService }, - { - provide: CryptoServiceAbstraction, - useClass: ElectronCryptoService, - deps: [ - CryptoFunctionServiceAbstraction, - PlatformUtilsServiceAbstraction, - LogServiceAbstraction, - StateServiceAbstraction, - ], - }, - { - provide: SystemServiceAbstraction, - useFactory: ( - messagingService: MessagingServiceAbstraction, - platformUtilsService: PlatformUtilsServiceAbstraction, - stateService: StateServiceAbstraction - ) => new SystemService(messagingService, platformUtilsService, null, stateService), - deps: [MessagingServiceAbstraction, PlatformUtilsServiceAbstraction, StateServiceAbstraction], - }, - { provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService }, - NativeMessagingService, - SearchBarService, - { - provide: LoginGuardService, - useClass: LoginGuardService, - deps: [StateServiceAbstraction, PlatformUtilsServiceAbstraction, I18nServiceAbstraction], - }, - { - provide: StateServiceAbstraction, - useFactory: ( - storageService: StorageServiceAbstraction, - secureStorageService: StorageServiceAbstraction, - logService: LogServiceAbstraction, - stateMigrationService: StateMigrationServiceAbstraction - ) => - new StateService( - storageService, - secureStorageService, - logService, - stateMigrationService, - new StateFactory(GlobalState, Account) - ), - deps: [ - StorageServiceAbstraction, - "SECURE_STORAGE", - LogServiceAbstraction, - StateMigrationServiceAbstraction, - ], - }, - { - provide: StateMigrationServiceAbstraction, - useFactory: ( - storageService: StorageServiceAbstraction, - secureStorageService: StorageServiceAbstraction - ) => - new StateMigrationService( - storageService, - secureStorageService, - new StateFactory(GlobalState, Account) - ), - deps: [StorageServiceAbstraction, "SECURE_STORAGE"], - }, - ], -}) -export class ServicesModule {} diff --git a/src/app/services/init.service.ts b/src/app/services/init.service.ts new file mode 100644 index 00000000..3bc3d49a --- /dev/null +++ b/src/app/services/init.service.ts @@ -0,0 +1,81 @@ +import { Inject, Injectable } from "@angular/core"; + +import { WINDOW } from "jslib-angular/services/jslib-services.module"; +import { CryptoService as CryptoServiceAbstraction } from "jslib-common/abstractions/crypto.service"; +import { EnvironmentService as EnvironmentServiceAbstraction } from "jslib-common/abstractions/environment.service"; +import { EventService as EventServiceAbstraction } from "jslib-common/abstractions/event.service"; +import { I18nService as I18nServiceAbstraction } from "jslib-common/abstractions/i18n.service"; +import { NotificationsService as NotificationsServiceAbstraction } from "jslib-common/abstractions/notifications.service"; +import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "jslib-common/abstractions/platformUtils.service"; +import { StateService as StateServiceAbstraction } from "jslib-common/abstractions/state.service"; +import { SyncService as SyncServiceAbstraction } from "jslib-common/abstractions/sync.service"; +import { TwoFactorService as TwoFactorServiceAbstraction } from "jslib-common/abstractions/twoFactor.service"; +import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "jslib-common/abstractions/vaultTimeout.service"; +import { ThemeType } from "jslib-common/enums/themeType"; +import { ContainerService } from "jslib-common/services/container.service"; +import { EventService } from "jslib-common/services/event.service"; +import { VaultTimeoutService } from "jslib-common/services/vaultTimeout.service"; + +import { I18nService } from "../../services/i18n.service"; +import { NativeMessagingService } from "../../services/nativeMessaging.service"; + +@Injectable() +export class InitService { + constructor( + @Inject(WINDOW) private win: Window, + private environmentService: EnvironmentServiceAbstraction, + private syncService: SyncServiceAbstraction, + private vaultTimeoutService: VaultTimeoutServiceAbstraction, + private i18nService: I18nServiceAbstraction, + private eventService: EventServiceAbstraction, + private twoFactorService: TwoFactorServiceAbstraction, + private notificationsService: NotificationsServiceAbstraction, + private platformUtilsService: PlatformUtilsServiceAbstraction, + private stateService: StateServiceAbstraction, + private cryptoService: CryptoServiceAbstraction, + private nativeMessagingService: NativeMessagingService + ) {} + + init() { + return async () => { + this.nativeMessagingService.init(); + await this.stateService.init(); + await this.environmentService.setUrlsFromStorage(); + this.syncService.fullSync(true); + (this.vaultTimeoutService as VaultTimeoutService).init(true); + const locale = await this.stateService.getLocale(); + await (this.i18nService as I18nService).init(locale); + (this.eventService as EventService).init(true); + this.twoFactorService.init(); + setTimeout(() => this.notificationsService.init(), 3000); + const htmlEl = this.win.document.documentElement; + htmlEl.classList.add("os_" + this.platformUtilsService.getDeviceString()); + + const theme = await this.platformUtilsService.getEffectiveTheme(); + htmlEl.classList.add("theme_" + theme); + this.platformUtilsService.onDefaultSystemThemeChange(async (sysTheme) => { + const bwTheme = await this.stateService.getTheme(); + if (bwTheme == null || bwTheme === ThemeType.System) { + htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark); + htmlEl.classList.add("theme_" + sysTheme); + } + }); + + let installAction = null; + const installedVersion = await this.stateService.getInstalledVersion(); + const currentVersion = await this.platformUtilsService.getApplicationVersion(); + if (installedVersion == null) { + installAction = "install"; + } else if (installedVersion !== currentVersion) { + installAction = "update"; + } + + if (installAction != null) { + await this.stateService.setInstalledVersion(currentVersion); + } + + const containerService = new ContainerService(this.cryptoService); + containerService.attachToGlobal(this.win); + }; + } +} diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts new file mode 100644 index 00000000..694cc6de --- /dev/null +++ b/src/app/services/services.module.ts @@ -0,0 +1,135 @@ +import { APP_INITIALIZER, InjectionToken, NgModule } from "@angular/core"; + +import { + JslibServicesModule, + SECURE_STORAGE, + STATE_FACTORY, + STATE_SERVICE_USE_CACHE, + WINDOW, + CLIENT_TYPE, + LOCALES_DIRECTORY, + SYSTEM_LANGUAGE, +} from "jslib-angular/services/jslib-services.module"; +import { BroadcasterService as BroadcasterServiceAbstraction } from "jslib-common/abstractions/broadcaster.service"; +import { CryptoService as CryptoServiceAbstraction } from "jslib-common/abstractions/crypto.service"; +import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "jslib-common/abstractions/cryptoFunction.service"; +import { I18nService as I18nServiceAbstraction } from "jslib-common/abstractions/i18n.service"; +import { + LogService, + LogService as LogServiceAbstraction, +} from "jslib-common/abstractions/log.service"; +import { MessagingService as MessagingServiceAbstraction } from "jslib-common/abstractions/messaging.service"; +import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "jslib-common/abstractions/passwordReprompt.service"; +import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "jslib-common/abstractions/platformUtils.service"; +import { StateService as StateServiceAbstraction } from "jslib-common/abstractions/state.service"; +import { StateMigrationService as StateMigrationServiceAbstraction } from "jslib-common/abstractions/stateMigration.service"; +import { StorageService as StorageServiceAbstraction } from "jslib-common/abstractions/storage.service"; +import { SystemService as SystemServiceAbstraction } from "jslib-common/abstractions/system.service"; +import { ClientType } from "jslib-common/enums/clientType"; +import { StateFactory } from "jslib-common/factories/stateFactory"; +import { GlobalState } from "jslib-common/models/domain/globalState"; +import { SystemService } from "jslib-common/services/system.service"; +import { ElectronCryptoService } from "jslib-electron/services/electronCrypto.service"; +import { ElectronLogService } from "jslib-electron/services/electronLog.service"; +import { ElectronPlatformUtilsService } from "jslib-electron/services/electronPlatformUtils.service"; +import { ElectronRendererMessagingService } from "jslib-electron/services/electronRendererMessaging.service"; +import { ElectronRendererSecureStorageService } from "jslib-electron/services/electronRendererSecureStorage.service"; +import { ElectronRendererStorageService } from "jslib-electron/services/electronRendererStorage.service"; + +import { Account } from "../../models/account"; +import { I18nService } from "../../services/i18n.service"; +import { LoginGuardService } from "../../services/loginGuard.service"; +import { NativeMessagingService } from "../../services/nativeMessaging.service"; +import { PasswordRepromptService } from "../../services/passwordReprompt.service"; +import { StateService } from "../../services/state.service"; +import { SearchBarService } from "../layout/search/search-bar.service"; + +import { InitService } from "./init.service"; + +const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK"); + +@NgModule({ + imports: [JslibServicesModule], + declarations: [], + providers: [ + InitService, + NativeMessagingService, + SearchBarService, + LoginGuardService, + { + provide: APP_INITIALIZER, + useFactory: (initService: InitService) => initService.init(), + deps: [InitService], + multi: true, + }, + { + provide: STATE_FACTORY, + useValue: new StateFactory(GlobalState, Account), + }, + { + provide: CLIENT_TYPE, + useValue: ClientType.Desktop, + }, + { + provide: RELOAD_CALLBACK, + useValue: null, + }, + { provide: LogServiceAbstraction, useClass: ElectronLogService, deps: [] }, + { + provide: PlatformUtilsServiceAbstraction, + useClass: ElectronPlatformUtilsService, + deps: [ + I18nServiceAbstraction, + MessagingServiceAbstraction, + CLIENT_TYPE, + StateServiceAbstraction, + ], + }, + { + provide: I18nServiceAbstraction, + useClass: I18nService, + deps: [SYSTEM_LANGUAGE, LOCALES_DIRECTORY], + }, + { + provide: MessagingServiceAbstraction, + useClass: ElectronRendererMessagingService, + deps: [BroadcasterServiceAbstraction], + }, + { provide: StorageServiceAbstraction, useClass: ElectronRendererStorageService }, + { provide: SECURE_STORAGE, useClass: ElectronRendererSecureStorageService }, + { + provide: CryptoServiceAbstraction, + useClass: ElectronCryptoService, + deps: [ + CryptoFunctionServiceAbstraction, + PlatformUtilsServiceAbstraction, + LogServiceAbstraction, + StateServiceAbstraction, + ], + }, + { + provide: SystemServiceAbstraction, + useClass: SystemService, + deps: [ + MessagingServiceAbstraction, + PlatformUtilsServiceAbstraction, + RELOAD_CALLBACK, + StateServiceAbstraction, + ], + }, + { provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService }, + { + provide: StateServiceAbstraction, + useClass: StateService, + deps: [ + StorageServiceAbstraction, + SECURE_STORAGE, + LogService, + StateMigrationServiceAbstraction, + STATE_FACTORY, + STATE_SERVICE_USE_CACHE, + ], + }, + ], +}) +export class ServicesModule {} diff --git a/src/app/vault/add-edit-custom-fields.component.html b/src/app/vault/add-edit-custom-fields.component.html index 9f5fc24a..0e5a8f6e 100644 --- a/src/app/vault/add-edit-custom-fields.component.html +++ b/src/app/vault/add-edit-custom-fields.component.html @@ -10,15 +10,14 @@ *ngFor="let f of cipher.fields; let i = index; trackBy: trackByFunction" [ngClass]="{ 'box-content-row-checkbox': f.type === fieldType.Boolean }" > - - +
@@ -78,12 +77,11 @@ class="action-buttons" *ngIf="f.type === fieldType.Hidden && (cipher.viewPassword || f.newField)" > - +
@@ -102,10 +100,10 @@
- +
- - +
- {{ "newUri" | i18n }} - +
@@ -477,9 +476,13 @@
-
{{ "attachments" | i18n }}
-
- +
diff --git a/src/app/vault/ciphers.component.html b/src/app/vault/ciphers.component.html index 1dbbb89c..90a70360 100644 --- a/src/app/vault/ciphers.component.html +++ b/src/app/vault/ciphers.component.html @@ -6,14 +6,15 @@ *ngIf="ciphers.length" > - +
diff --git a/src/app/vault/generator.component.html b/src/app/vault/generator.component.html index fad3a231..79c9bf5b 100644 --- a/src/app/vault/generator.component.html +++ b/src/app/vault/generator.component.html @@ -41,7 +41,7 @@
-
+
@@ -371,6 +376,62 @@
+ +
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+ +
+ + +
+
diff --git a/src/app/vault/generator.component.ts b/src/app/vault/generator.component.ts index 553f53b2..471fd971 100644 --- a/src/app/vault/generator.component.ts +++ b/src/app/vault/generator.component.ts @@ -3,6 +3,7 @@ import { ActivatedRoute } from "@angular/router"; import { GeneratorComponent as BaseGeneratorComponent } from "jslib-angular/components/generator.component"; import { I18nService } from "jslib-common/abstractions/i18n.service"; +import { LogService } from "jslib-common/abstractions/log.service"; import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service"; import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service"; import { StateService } from "jslib-common/abstractions/state.service"; @@ -19,7 +20,8 @@ export class GeneratorComponent extends BaseGeneratorComponent { stateService: StateService, platformUtilsService: PlatformUtilsService, i18nService: I18nService, - route: ActivatedRoute + route: ActivatedRoute, + logService: LogService ) { super( passwordGenerationService, @@ -27,6 +29,7 @@ export class GeneratorComponent extends BaseGeneratorComponent { platformUtilsService, stateService, i18nService, + logService, route, window ); diff --git a/src/app/vault/groupings.component.html b/src/app/vault/groupings.component.html index 276c7f57..148c21d1 100644 --- a/src/app/vault/groupings.component.html +++ b/src/app/vault/groupings.component.html @@ -3,44 +3,86 @@

{{ "filters" | i18n }}

{{ "types" | i18n }}

{{ "loading" | i18n }}

@@ -57,7 +99,13 @@ *ngFor="let f of folders" [ngClass]="{ active: selectedFolder && f.node.id === selectedFolderId }" > - +
- - +
diff --git a/src/app/vault/password-history.component.html b/src/app/vault/password-history.component.html index 8ce5b059..633cee14 100644 --- a/src/app/vault/password-history.component.html +++ b/src/app/vault/password-history.component.html @@ -15,16 +15,15 @@ {{ h.lastUsedDate | date: "medium" }}
- - +
diff --git a/src/app/vault/view-custom-fields.component.html b/src/app/vault/view-custom-fields.component.html index a180885f..d1980048 100644 --- a/src/app/vault/view-custom-fields.component.html +++ b/src/app/vault/view-custom-fields.component.html @@ -35,24 +35,23 @@
diff --git a/src/app/vault/view.component.html b/src/app/vault/view.component.html index 3a2b12ef..255d0e76 100644 --- a/src/app/vault/view.component.html +++ b/src/app/vault/view.component.html @@ -22,16 +22,15 @@ {{ cipher.login.username }}
- - +
@@ -74,31 +73,29 @@ aria-hidden="true" > - - - +
- - +
@@ -153,35 +149,37 @@
{{ "number" | i18n }} - {{ cipher.card.maskedNumber }} - {{ cipher.card.number }} + {{ + cipher.card.maskedNumber | creditCardNumber: cipher.card.brand + }} + {{ + cipher.card.number | creditCardNumber: cipher.card.brand + }}
@@ -199,31 +197,29 @@ {{ cipher.card.code }}
- - - +
@@ -289,27 +285,25 @@ {{ u.hostOrUri }}
- - - +
@@ -334,10 +328,10 @@ {{ "attachments" | i18n }}
- +
@@ -369,15 +363,14 @@
{{ "passwordHistory" | i18n }}: - - +
diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index af873f0c..e204d4d5 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -1853,6 +1853,12 @@ } } }, + "locked": { + "message": "Locked" + }, + "unlocked": { + "message": "Unlocked" + }, "generator": { "message": "Generator" }, @@ -1895,5 +1901,21 @@ }, "service": { "message": "Service" + }, + "forwardedEmail": { + "message": "Forwarded Email Alias" + }, + "forwardedEmailDesc": { + "message": "Generate an email alias with an external forwarding service." + }, + "hostname": { + "message": "Hostname", + "description": "Part of a URL." + }, + "apiAccessToken": { + "message": "API Access Token" + }, + "apiKey": { + "message": "API Key" } } diff --git a/src/main/desktopCredentialStorageListener.ts b/src/main/desktopCredentialStorageListener.ts index 70c9c7c9..1c6d06b0 100644 --- a/src/main/desktopCredentialStorageListener.ts +++ b/src/main/desktopCredentialStorageListener.ts @@ -1,5 +1,5 @@ -import { passwords } from "@bitwarden/desktop-native"; import { ipcMain } from "electron"; +import { deletePassword, getPassword, setPassword } from "keytar"; import { BiometricMain } from "./biometric/biometric.main"; @@ -25,14 +25,14 @@ export class DesktopCredentialStorageListener { let val: string | boolean = null; if (authenticated && message.action && message.key) { if (message.action === "getPassword") { - val = await this.getPassword(serviceName, message.key); + val = await getPassword(serviceName, message.key); } else if (message.action === "hasPassword") { - const result = await this.getPassword(serviceName, message.key); + const result = await getPassword(serviceName, message.key); val = result != null; } else if (message.action === "setPassword" && message.value) { - await passwords.setPassword(serviceName, message.key, message.value); + await setPassword(serviceName, message.key, message.value); } else if (message.action === "deletePassword") { - await passwords.deletePassword(serviceName, message.key); + await deletePassword(serviceName, message.key); } } event.returnValue = val; @@ -42,18 +42,6 @@ export class DesktopCredentialStorageListener { }); } - // Gracefully handle old keytar values, and if detected updated the entry to the proper format - private async getPassword(serviceName: string, key: string) { - let val = await passwords.getPassword(serviceName, key); - try { - JSON.parse(val); - } catch (e) { - val = await passwords.getPasswordKeytar(serviceName, key); - await passwords.setPassword(serviceName, key, val); - } - return val; - } - private async authenticateBiometric(): Promise { if (this.biometricService) { return await this.biometricService.authenticateBiometric(); diff --git a/src/package-lock.json b/src/package-lock.json index a34fc70f..a8c141bc 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -1,33 +1,19 @@ { "name": "@bitwarden/desktop", - "version": "1.32.2", + "version": "1.33.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "1.32.2", + "version": "1.33.1", "license": "GPL-3.0", "dependencies": { - "@bitwarden/desktop-native": "file:../desktop_native", "@nodert-win10-rs4/windows.security.credentials.ui": "^0.4.4", - "forcefocus": "^1.1.0" + "forcefocus": "^1.1.0", + "keytar": "^7.9.0" } }, - "../desktop_native": { - "name": "@bitwarden/desktop_native", - "version": "0.1.0", - "hasInstallScript": true, - "license": "GPL-3.0", - "devDependencies": { - "@napi-rs/cli": "^2.4.4", - "cargo-cp-artifact": "^0.1" - } - }, - "node_modules/@bitwarden/desktop-native": { - "resolved": "../desktop_native", - "link": true - }, "node_modules/@nodert-win10-rs4/windows.security.credentials.ui": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/@nodert-win10-rs4/windows.security.credentials.ui/-/windows.security.credentials.ui-0.4.4.tgz", @@ -299,6 +285,135 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "node_modules/keytar/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/keytar/node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/keytar/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/keytar/node_modules/node-abi": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.15.0.tgz", + "integrity": "sha512-Ic6z/j6I9RLm4ov7npo1I48UQr2BEyFCqh6p7S1dhEx9jPO0GPGq/e2Rb7x7DroQrmiVMz/Bw1vJm9sPAl2nxA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/keytar/node_modules/prebuild-install": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.0.tgz", + "integrity": "sha512-CNcMgI1xBypOyGqjp3wOc8AAo1nMhZS3Cwd3iHIxOdAUbb+YxdNuM4Z5iIrZ8RLvOsf3F3bl7b7xGq6DjQoNYA==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/keytar/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/keytar/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", @@ -338,6 +453,11 @@ "semver": "^5.4.1" } }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, "node_modules/noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", @@ -615,16 +735,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } }, "dependencies": { - "@bitwarden/desktop-native": { - "version": "file:../desktop_native", - "requires": { - "@napi-rs/cli": "^2.4.4", - "cargo-cp-artifact": "^0.1" - } - }, "@nodert-win10-rs4/windows.security.credentials.ui": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/@nodert-win10-rs4/windows.security.credentials.ui/-/windows.security.credentials.ui-0.4.4.tgz", @@ -824,6 +942,89 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "requires": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + }, + "dependencies": { + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, + "node-abi": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.15.0.tgz", + "integrity": "sha512-Ic6z/j6I9RLm4ov7npo1I48UQr2BEyFCqh6p7S1dhEx9jPO0GPGq/e2Rb7x7DroQrmiVMz/Bw1vJm9sPAl2nxA==", + "requires": { + "semver": "^7.3.5" + } + }, + "prebuild-install": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.0.tgz", + "integrity": "sha512-CNcMgI1xBypOyGqjp3wOc8AAo1nMhZS3Cwd3iHIxOdAUbb+YxdNuM4Z5iIrZ8RLvOsf3F3bl7b7xGq6DjQoNYA==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, "mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", @@ -857,6 +1058,11 @@ "semver": "^5.4.1" } }, + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", @@ -1083,6 +1289,11 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/src/package.json b/src/package.json index 3e7ab7e0..1dc98451 100644 --- a/src/package.json +++ b/src/package.json @@ -12,8 +12,8 @@ "url": "https://github.com/bitwarden/desktop" }, "dependencies": { - "@bitwarden/desktop-native": "file:../desktop_native", "@nodert-win10-rs4/windows.security.credentials.ui": "^0.4.4", - "forcefocus": "^1.1.0" + "forcefocus": "^1.1.0", + "keytar": "^7.9.0" } } diff --git a/src/scss/base.scss b/src/scss/base.scss index 4c9445da..70889595 100644 --- a/src/scss/base.scss +++ b/src/scss/base.scss @@ -84,6 +84,9 @@ button { } button { + border: none; + background: transparent; + color: inherit; white-space: nowrap; cursor: pointer; } diff --git a/src/scss/box.scss b/src/scss/box.scss index ddb7bcca..a955617f 100644 --- a/src/scss/box.scss +++ b/src/scss/box.scss @@ -105,9 +105,11 @@ .box-content-row { display: block; + width: 100%; padding: 10px 15px; position: relative; z-index: 1; + text-align: left; &:before { content: ""; @@ -232,7 +234,8 @@ margin-top: 5px; } - > a { + > a, + > button { padding: 8px 8px 8px 4px; margin: 0; @@ -366,7 +369,7 @@ &:not(.box-draggable-row) { .action-buttons .row-btn:last-child { - padding-right: 2px !important; + margin-right: -6px !important; } } diff --git a/src/scss/list.scss b/src/scss/list.scss index fb6ddac3..45288e5e 100644 --- a/src/scss/list.scss +++ b/src/scss/list.scss @@ -1,10 +1,8 @@ @import "variables.scss"; -.list > a { - display: block; +.list > button { padding: 3px 10px; text-decoration: none; - position: relative; user-select: none; z-index: 1; @@ -105,11 +103,14 @@ } } -.list > a.flex-list-item { +.list > button.flex-list-item { display: flex; align-items: center; + width: 100%; + text-align: left; .item-icon { + display: block; margin-left: -5px; margin-right: 4px; @include themify($themes) { @@ -118,7 +119,9 @@ } .item-content { + display: block; .item-title { + display: block; .title-badges { @include themify($themes) { color: themed("mutedColor"); @@ -135,12 +138,12 @@ } .flex-cipher-list-item { - flex-direction: column; - flex-wrap: nowrap; - justify-content: center; - align-items: flex-start; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + + > * { + text-align: left; + } } } diff --git a/src/scss/vault.scss b/src/scss/vault.scss index 168a23e9..adef1984 100644 --- a/src/scss/vault.scss +++ b/src/scss/vault.scss @@ -43,7 +43,7 @@ app-root { order: 1; width: 22%; min-width: 175px; - max-width: 250px; + max-width: 600px; border-right: 1px solid #000000; @include themify($themes) { @@ -129,7 +129,7 @@ app-root { ul.bwi-ul { // Level 1 li { - > a { + > button { padding-left: 12px; } @@ -137,14 +137,14 @@ app-root { left: -4px; } - &.active > a .bwi-li { + &.active > button .bwi-li { left: 11px; } } // Level 2 ul li { - > a { + > button { padding-left: 23px; } @@ -152,14 +152,14 @@ app-root { left: 7px; } - &.active > a .bwi-li { + &.active > button .bwi-li { left: 22px; } } // Level 3 ul ul li { - > a { + > button { padding-left: 34px; } @@ -167,14 +167,14 @@ app-root { left: 18px; } - &.active > a .bwi-li { + &.active > button .bwi-li { left: 33px; } } // Level 4 ul ul ul li { - > a { + > button { padding-left: 45px; } @@ -182,14 +182,14 @@ app-root { left: 29px; } - &.active > a .bwi-li { + &.active > button .bwi-li { left: 44px; } } // Level 5 ul ul ul ul li { - > a { + > button { padding-left: 56px; } @@ -197,14 +197,14 @@ app-root { left: 40px; } - &.active > a .bwi-li { + &.active > button .bwi-li { left: 55px; } } // Level 6 ul ul ul ul ul li { - > a { + > button { padding-left: 67px; } @@ -212,14 +212,14 @@ app-root { left: 51px; } - &.active > a .bwi-li { + &.active > button .bwi-li { left: 66px; } } // Level 7 ul ul ul ul ul ul li { - > a { + > button { padding-left: 78px; } @@ -227,7 +227,7 @@ app-root { left: 62px; } - &.active > a .bwi-li { + &.active > button .bwi-li { left: 77px; } } @@ -238,10 +238,11 @@ app-root { margin: 0; li { - a { + button { padding: 5px 0; display: flex; align-items: center; + width: 100%; @include themify($themes) { color: themed("textColor");