Skip to content

Commit 805d2e4

Browse files
feat(keystore/wasm): migrate credentials to new object store
1 parent b14d5d5 commit 805d2e4

File tree

2 files changed

+69
-0
lines changed
  • keystore/src/connection/platform/wasm/migrations

2 files changed

+69
-0
lines changed

keystore/src/connection/platform/wasm/migrations/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod v5;
88
mod v6;
99
mod v7;
1010
mod v8;
11+
mod v9;
1112

1213
pub(super) use db_key_type_to_bytes::migrate_db_key_type_to_bytes;
1314
use idb::{Database, Factory};
@@ -32,6 +33,7 @@ const DB_VERSION_5: u32 = db_version_number(5);
3233
const DB_VERSION_6: u32 = db_version_number(6);
3334
const DB_VERSION_7: u32 = db_version_number(7);
3435
const DB_VERSION_8: u32 = db_version_number(8);
36+
const DB_VERSION_9: u32 = db_version_number(9);
3537

3638
/// Open an existing idb database with the given name, and migrate it if needed.
3739
pub(crate) async fn open_and_migrate(name: &str, key: &DatabaseKey) -> CryptoKeystoreResult<Database> {
@@ -77,6 +79,7 @@ async fn do_migration_step(from: u32, name: &str, key: &DatabaseKey) -> CryptoKe
7779
DB_VERSION_5 => v6::migrate(name, key).await,
7880
DB_VERSION_6 => v7::migrate(name, key).await,
7981
DB_VERSION_7 => v8::migrate(name, key).await,
82+
DB_VERSION_8 => v9::migrate(name, key).await,
8083
_ => Err(CryptoKeystoreError::MigrationNotSupported(from)),
8184
}
8285
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//! This migration queries all credentials from the credential store, inserts them into the new one, then removes the
2+
//! old store and renames the new one.
3+
4+
use idb::builder::DatabaseBuilder;
5+
use serde::Serialize as _;
6+
7+
use super::DB_VERSION_9;
8+
use crate::{
9+
CryptoKeystoreResult, Database, DatabaseKey,
10+
connection::platform::wasm::WasmStorageTransaction,
11+
entities::{Entity as _, EntityBase, StoredCredential},
12+
};
13+
14+
/// Open IDB once with the new builder and close it, this will apply the update.
15+
pub(super) async fn migrate(name: &str, key: &DatabaseKey) -> CryptoKeystoreResult<u32> {
16+
let db_before_migration = Database::open(crate::ConnectionType::Persistent(name), key).await?;
17+
let connection = db_before_migration.conn().await?;
18+
let credentials = connection
19+
.storage()
20+
.get_all::<StoredCredential>(StoredCredential::COLLECTION_NAME, None)
21+
.await?;
22+
23+
let collection_name = format!(
24+
"{collection_name}_new",
25+
collection_name = StoredCredential::COLLECTION_NAME
26+
);
27+
28+
db_before_migration.new_transaction().await?;
29+
let mut tx_creator = connection.conn().await;
30+
let mut tx = tx_creator.new_transaction(&[&collection_name]).await?;
31+
32+
for mut credential in credentials {
33+
let serializer = serde_wasm_bindgen::Serializer::json_compatible();
34+
let key = &js_sys::Uint8Array::from(credential.public_key.as_slice()).into();
35+
match tx {
36+
WasmStorageTransaction::Persistent { ref mut tx, cipher } => {
37+
credential.encrypt(cipher)?;
38+
let js_value = credential.serialize(&serializer)?;
39+
let store = tx.object_store(&collection_name)?;
40+
store.put(&js_value, Some(key))?.await?;
41+
}
42+
WasmStorageTransaction::InMemory { .. } => {
43+
// in memory transaction is never used in production.
44+
}
45+
}
46+
}
47+
48+
tx.commit_tx().await?;
49+
db_before_migration.close().await?;
50+
51+
let migrated_idb = get_builder(name).build().await?;
52+
let version = migrated_idb.version()?;
53+
migrated_idb.close();
54+
Ok(version)
55+
}
56+
57+
/// Set up the builder for v9.
58+
pub(super) fn get_builder(name: &str) -> DatabaseBuilder {
59+
let collection_name = StoredCredential::COLLECTION_NAME;
60+
let collection_name_with_prefix = &format!("{collection_name}-new",);
61+
62+
super::v8::get_builder(name)
63+
.version(DB_VERSION_9)
64+
.remove_object_store(collection_name)
65+
.rename_object_store(collection_name_with_prefix, collection_name)
66+
}

0 commit comments

Comments
 (0)