From 99d5178058a6a9c334885cfc0dcce426a0d420bf Mon Sep 17 00:00:00 2001 From: Hinton Date: Mon, 25 Mar 2024 10:55:53 +0100 Subject: [PATCH 01/11] Expose argon2 in wasm --- Cargo.lock | 2 ++ crates/bitwarden-wasm/Cargo.toml | 14 +++++++++----- crates/bitwarden-wasm/src/client.rs | 28 ++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfa714cc6..53e71bc95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,6 +521,8 @@ dependencies = [ name = "bitwarden-wasm" version = "0.1.0" dependencies = [ + "argon2", + "base64", "bitwarden-json", "console_error_panic_hook", "console_log", diff --git a/crates/bitwarden-wasm/Cargo.toml b/crates/bitwarden-wasm/Cargo.toml index a688f12b6..f715ea11a 100644 --- a/crates/bitwarden-wasm/Cargo.toml +++ b/crates/bitwarden-wasm/Cargo.toml @@ -15,6 +15,15 @@ keywords.workspace = true crate-type = ["cdylib"] [dependencies] +argon2 = { version = ">=0.5.0, <0.6", features = [ + "alloc", + "zeroize", +], default-features = false } +base64 = ">=0.21.2, <0.22" +bitwarden-json = { path = "../bitwarden-json", features = [ + "secrets", + "internal", +] } console_error_panic_hook = "0.1.7" console_log = { version = "1.0.0", features = ["color"] } js-sys = "0.3.68" @@ -23,10 +32,5 @@ serde = { version = "1.0.196", features = ["derive"] } wasm-bindgen = { version = "0.2.91", features = ["serde-serialize"] } wasm-bindgen-futures = "0.4.41" -bitwarden-json = { path = "../bitwarden-json", features = [ - "secrets", - "internal", -] } - [dev-dependencies] wasm-bindgen-test = "0.3.41" diff --git a/crates/bitwarden-wasm/src/client.rs b/crates/bitwarden-wasm/src/client.rs index 542759731..c3599594b 100644 --- a/crates/bitwarden-wasm/src/client.rs +++ b/crates/bitwarden-wasm/src/client.rs @@ -1,6 +1,8 @@ extern crate console_error_panic_hook; use std::rc::Rc; +use argon2::{Algorithm, Argon2, Params, Version}; +use base64::{engine::general_purpose::STANDARD, Engine}; use bitwarden_json::client::Client as JsonClient; use js_sys::Promise; use log::Level; @@ -54,3 +56,29 @@ impl BitwardenClient { }) } } + +#[wasm_bindgen] +pub fn argon2( + password: &[u8], + salt: &[u8], + iterations: u32, + memory: u32, + parallelism: u32, +) -> String { + let argon = Argon2::new( + Algorithm::Argon2id, + Version::V0x13, + Params::new( + memory * 1024, // Convert MiB to KiB + iterations, + parallelism, + Some(32), + ) + .unwrap(), + ); + + let mut hash = [0u8; 32]; + argon.hash_password_into(password, salt, &mut hash).unwrap(); + + STANDARD.encode(hash) +} From a1d80e73023cbfc1ae21048af4cd7d17fa440398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 1 Apr 2024 13:12:02 +0200 Subject: [PATCH 02/11] Change wasm argon2 to use vec --- crates/bitwarden-wasm/src/client.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/bitwarden-wasm/src/client.rs b/crates/bitwarden-wasm/src/client.rs index c3599594b..f6ac322b8 100644 --- a/crates/bitwarden-wasm/src/client.rs +++ b/crates/bitwarden-wasm/src/client.rs @@ -2,7 +2,6 @@ extern crate console_error_panic_hook; use std::rc::Rc; use argon2::{Algorithm, Argon2, Params, Version}; -use base64::{engine::general_purpose::STANDARD, Engine}; use bitwarden_json::client::Client as JsonClient; use js_sys::Promise; use log::Level; @@ -64,7 +63,7 @@ pub fn argon2( iterations: u32, memory: u32, parallelism: u32, -) -> String { +) -> Vec { let argon = Argon2::new( Algorithm::Argon2id, Version::V0x13, @@ -79,6 +78,5 @@ pub fn argon2( let mut hash = [0u8; 32]; argon.hash_password_into(password, salt, &mut hash).unwrap(); - - STANDARD.encode(hash) + hash.to_vec() } From 7d15daf2cb3c3e2f3945f211dd0493ce40bc6c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 1 Apr 2024 13:26:45 +0200 Subject: [PATCH 03/11] Build wasm workflow --- .github/workflows/build-wasm.yml | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/build-wasm.yml diff --git a/.github/workflows/build-wasm.yml b/.github/workflows/build-wasm.yml new file mode 100644 index 000000000..b7cc65a73 --- /dev/null +++ b/.github/workflows/build-wasm.yml @@ -0,0 +1,58 @@ +--- +name: Build @bitwarden/sdk-wasm + +on: + pull_request: + push: + branches: + - "main" + - "rc" + - "hotfix-rc" + workflow_dispatch: + +defaults: + run: + shell: bash + working-directory: crates/bitwarden-wasm + +jobs: + build: + name: Building @bitwarden/sdk-wasm + runs-on: ubuntu-22.04 + + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Node + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: "npm" + + - name: Install dependencies + run: npm i -g binaryen + + - name: Install rust + uses: dtolnay/rust-toolchain@be73d7920c329f220ce78e0234b8f96b7ae60248 # stable + with: + toolchain: stable + targets: wasm32-unknown-unknown + + - name: Cache cargo registry + uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3 + with: + key: wasm-cargo-${{ matrix.settings.os }} + + - name: Install wasm-bindgen-cli + run: cargo install wasm-bindgen-cli + + - name: Build + run: ./build.sh -r + + - name: Upload artifact + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + with: + name: sdk-bitwarden-wasm + path: ${{ github.workspace }}/languages/js/wasm/* + if-no-files-found: error From f6c6da7869dba496f87f77c74f40e9961c5089fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 1 Apr 2024 15:11:21 +0200 Subject: [PATCH 04/11] Publish wasm workflow --- .github/workflows/build-wasm.yml | 2 +- .github/workflows/release-wasm.yml | 143 +++++++++++++++++++++++++++++ languages/js/wasm/package.json | 1 + 3 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release-wasm.yml diff --git a/.github/workflows/build-wasm.yml b/.github/workflows/build-wasm.yml index b7cc65a73..621a948a6 100644 --- a/.github/workflows/build-wasm.yml +++ b/.github/workflows/build-wasm.yml @@ -42,7 +42,7 @@ jobs: - name: Cache cargo registry uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3 with: - key: wasm-cargo-${{ matrix.settings.os }} + key: wasm-cargo-cache - name: Install wasm-bindgen-cli run: cargo install wasm-bindgen-cli diff --git a/.github/workflows/release-wasm.yml b/.github/workflows/release-wasm.yml new file mode 100644 index 000000000..27f765d6e --- /dev/null +++ b/.github/workflows/release-wasm.yml @@ -0,0 +1,143 @@ +--- +name: Release @bitwarden/sdk-wasm +run-name: Release @bitwarden/sdk-wasm ${{ inputs.release_type }} + +on: + workflow_dispatch: + inputs: + release_type: + description: "Release Options" + required: true + default: "Initial Release" + type: choice + options: + - Initial Release + - Redeploy + - Dry Run + npm_publish: + description: "Publish to NPM registry" + required: true + default: true + type: boolean + +defaults: + run: + shell: bash + working-directory: languages/js/wasm + +jobs: + setup: + name: Setup + runs-on: ubuntu-22.04 + outputs: + release-version: ${{ steps.version.outputs.version }} + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Branch check + if: ${{ github.event.inputs.release_type != 'Dry Run' }} + run: | + if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then + echo "===================================" + echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches" + echo "===================================" + exit 1 + fi + + - name: Check Release Version + id: version + uses: bitwarden/gh-actions/release-version-check@main + with: + release-type: ${{ github.event.inputs.release_type }} + project-type: ts + file: languages/js/wasm/package.json + monorepo: false + + - name: Create GitHub deployment + if: ${{ github.event.inputs.release_type != 'Dry Run' }} + uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7 + id: deployment + with: + token: "${{ secrets.GITHUB_TOKEN }}" + initial-status: "in_progress" + environment: "Bitwarden SDK WASM - Production" + description: "Deployment ${{ steps.version.outputs.version }} from branch ${{ github.ref_name }}" + task: release + + - name: Update deployment status to Success + if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }} + uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + with: + token: "${{ secrets.GITHUB_TOKEN }}" + state: "success" + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + + - name: Update deployment status to Failure + if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }} + uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1 + with: + token: "${{ secrets.GITHUB_TOKEN }}" + state: "failure" + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + + npm: + name: Publish NPM + runs-on: ubuntu-22.04 + needs: setup + if: inputs.npm_publish + env: + _PKG_VERSION: ${{ needs.setup.outputs.release-version }} + steps: + - name: Checkout repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Node + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: "npm" + + - name: Login to Azure + uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 + with: + creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} + + - name: Retrieve secrets + id: retrieve-secrets + uses: bitwarden/gh-actions/get-keyvault-secrets@main + with: + keyvault: "bitwarden-ci" + secrets: "npm-api-key" + + - name: Download artifacts + if: ${{ github.event.inputs.release_type != 'Dry Run' }} + uses: bitwarden/gh-actions/download-artifacts@main + with: + workflow: build-wasm.yml + path: ${{ github.workspace }}/languages/js/wasm + workflow_conclusion: success + branch: ${{ github.ref_name }} + + - name: Dry Run - Download artifacts + if: ${{ github.event.inputs.release_type == 'Dry Run' }} + uses: bitwarden/gh-actions/download-artifacts@main + with: + workflow: build-wasm.yml + path: ${{ github.workspace }}/languages/js/wasm + workflow_conclusion: success + branch: main + + - name: Setup NPM + run: | + echo 'registry="https://registry.npmjs.org/"' > ./.npmrc + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ./.npmrc + + echo 'registry="https://registry.npmjs.org/"' > ~/.npmrc + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + env: + NPM_TOKEN: ${{ steps.retrieve-secrets.outputs.npm-api-key }} + + - name: Publish NPM + if: ${{ github.event.inputs.release_type != 'Dry Run' }} + run: npm publish --access public --registry=https://registry.npmjs.org/ --userconfig=./.npmrc diff --git a/languages/js/wasm/package.json b/languages/js/wasm/package.json index 26379c9a6..5340e1fd7 100644 --- a/languages/js/wasm/package.json +++ b/languages/js/wasm/package.json @@ -15,6 +15,7 @@ "main": "node/bitwarden_wasm.js", "module": "index.js", "types": "bitwarden_wasm.d.ts", + "scripts": {}, "sideEffects": [ "./bitwarden_wasm.js", "./snippets/*" From 30881a4d7f367fa2aa77b6308c67e2e296b4a7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 1 Apr 2024 15:36:58 +0200 Subject: [PATCH 05/11] Prettier --- .github/workflows/build-wasm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-wasm.yml b/.github/workflows/build-wasm.yml index 621a948a6..0bc29b4e0 100644 --- a/.github/workflows/build-wasm.yml +++ b/.github/workflows/build-wasm.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - + - name: Setup Node uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: From be94ec6815ee83b803f02b37b93bf3a6e4e1f18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 1 Apr 2024 18:11:35 +0200 Subject: [PATCH 06/11] Fix missing files in package.json --- languages/js/wasm/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/languages/js/wasm/package.json b/languages/js/wasm/package.json index 5340e1fd7..eadbb5fb3 100644 --- a/languages/js/wasm/package.json +++ b/languages/js/wasm/package.json @@ -4,11 +4,13 @@ "files": [ "bitwarden_wasm_bg.js", "bitwarden_wasm_bg.wasm", + "bitwarden_wasm_bg.wasm.d.ts", + "bitwarden_wasm_bg.wasm.js", "bitwarden_wasm.d.ts", "bitwarden_wasm.js", "index.js", - "node/bitwarden_wasm_bg.wasm.d.ts", "node/bitwarden_wasm_bg.wasm", + "node/bitwarden_wasm_bg.wasm.d.ts", "node/bitwarden_wasm.d.ts", "node/bitwarden_wasm.js" ], From affe24cc326e90b14e33cd635ad95bc47eeab388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Tue, 2 Apr 2024 11:56:45 +0200 Subject: [PATCH 07/11] Apply review comments --- .github/workflows/release-wasm.yml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release-wasm.yml b/.github/workflows/release-wasm.yml index 27f765d6e..89ae146ad 100644 --- a/.github/workflows/release-wasm.yml +++ b/.github/workflows/release-wasm.yml @@ -8,10 +8,10 @@ on: release_type: description: "Release Options" required: true - default: "Initial Release" + default: "Release" type: choice options: - - Initial Release + - Release - Redeploy - Dry Run npm_publish: @@ -111,22 +111,12 @@ jobs: secrets: "npm-api-key" - name: Download artifacts - if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: bitwarden/gh-actions/download-artifacts@main - with: - workflow: build-wasm.yml - path: ${{ github.workspace }}/languages/js/wasm - workflow_conclusion: success - branch: ${{ github.ref_name }} - - - name: Dry Run - Download artifacts - if: ${{ github.event.inputs.release_type == 'Dry Run' }} uses: bitwarden/gh-actions/download-artifacts@main with: workflow: build-wasm.yml path: ${{ github.workspace }}/languages/js/wasm workflow_conclusion: success - branch: main + branch: ${{ github.event.inputs.release_type == 'Dry Run' && 'main' || github.ref_name }} - name: Setup NPM run: | From 38fd5a514ddc801bcae6e0d37060c5ed71f493e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 3 Apr 2024 15:05:22 +0200 Subject: [PATCH 08/11] Remove redeploy --- .github/workflows/release-wasm.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release-wasm.yml b/.github/workflows/release-wasm.yml index 89ae146ad..c4946a0e1 100644 --- a/.github/workflows/release-wasm.yml +++ b/.github/workflows/release-wasm.yml @@ -12,7 +12,6 @@ on: type: choice options: - Release - - Redeploy - Dry Run npm_publish: description: "Publish to NPM registry" From 1a521201552a76c247acd438b5333af147c2d2f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Tue, 9 Apr 2024 11:11:47 +0200 Subject: [PATCH 09/11] Remove unused base64 --- Cargo.lock | 1 - crates/bitwarden-wasm/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53e71bc95..fd7c3388f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -522,7 +522,6 @@ name = "bitwarden-wasm" version = "0.1.0" dependencies = [ "argon2", - "base64", "bitwarden-json", "console_error_panic_hook", "console_log", diff --git a/crates/bitwarden-wasm/Cargo.toml b/crates/bitwarden-wasm/Cargo.toml index f715ea11a..53687f9ac 100644 --- a/crates/bitwarden-wasm/Cargo.toml +++ b/crates/bitwarden-wasm/Cargo.toml @@ -19,7 +19,6 @@ argon2 = { version = ">=0.5.0, <0.6", features = [ "alloc", "zeroize", ], default-features = false } -base64 = ">=0.21.2, <0.22" bitwarden-json = { path = "../bitwarden-json", features = [ "secrets", "internal", From 49f99786da3a3607a8708c2a790d53a068d60758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Tue, 9 Apr 2024 11:34:37 +0200 Subject: [PATCH 10/11] Switch to results --- crates/bitwarden-wasm/src/client.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/bitwarden-wasm/src/client.rs b/crates/bitwarden-wasm/src/client.rs index f6ac322b8..6bf45cb30 100644 --- a/crates/bitwarden-wasm/src/client.rs +++ b/crates/bitwarden-wasm/src/client.rs @@ -63,7 +63,7 @@ pub fn argon2( iterations: u32, memory: u32, parallelism: u32, -) -> Vec { +) -> Result, JsError> { let argon = Argon2::new( Algorithm::Argon2id, Version::V0x13, @@ -72,11 +72,10 @@ pub fn argon2( iterations, parallelism, Some(32), - ) - .unwrap(), + )?, ); let mut hash = [0u8; 32]; - argon.hash_password_into(password, salt, &mut hash).unwrap(); - hash.to_vec() + argon.hash_password_into(password, salt, &mut hash)?; + Ok(Vec::new()) } From db5b055abd0105bd2d0b8bcf4714545f09acf20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Tue, 9 Apr 2024 11:47:49 +0200 Subject: [PATCH 11/11] Actually return the value --- crates/bitwarden-wasm/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bitwarden-wasm/src/client.rs b/crates/bitwarden-wasm/src/client.rs index 6bf45cb30..bca8c2383 100644 --- a/crates/bitwarden-wasm/src/client.rs +++ b/crates/bitwarden-wasm/src/client.rs @@ -77,5 +77,5 @@ pub fn argon2( let mut hash = [0u8; 32]; argon.hash_password_into(password, salt, &mut hash)?; - Ok(Vec::new()) + Ok(hash.to_vec()) }