use bitwarden_crypto::SymmetricCryptoKey;
use tracing::info;
use crate::{
Client,
key_management::{self, SymmetricKeySlotId},
};
const USER_KEY_REPOSITORY_KEY: &str = "";
pub(crate) struct UnableToSetError;
pub(crate) async fn copy_user_key_to_client_managed_state(
client: &Client,
) -> Result<(), UnableToSetError> {
let user_key = {
let key_store = client.internal.get_key_store();
let ctx = key_store.context();
#[expect(deprecated)]
ctx.dangerous_get_symmetric_key(SymmetricKeySlotId::User)
.map_err(|_| UnableToSetError)?
.clone()
};
if let Ok(user_key_repository) = client
.platform()
.state()
.get::<key_management::UserKeyState>()
{
if let Ok(Some(existing_key)) = user_key_repository
.get(USER_KEY_REPOSITORY_KEY.to_string())
.await
{
if SymmetricCryptoKey::try_from(existing_key.decrypted_user_key)
.map_err(|_| UnableToSetError)?
== user_key
{
info!("User-key in client managed state is already up to date, skipping set");
return Ok(());
} else {
info!("User-key in client managed state is outdated, updating it");
}
} else {
info!("No user-key in client managed state, setting it");
}
} else {
info!("No UserKeyState repository exists in client managed state, exiting gracefully");
return Ok(());
}
info!("Setting the user-key to client managed-state from SDK");
client
.platform()
.state()
.get::<key_management::UserKeyState>()
.map_err(|_| UnableToSetError)?
.set(
USER_KEY_REPOSITORY_KEY.to_string(),
key_management::UserKeyState {
decrypted_user_key: user_key.to_base64(),
},
)
.await
.map_err(|_| UnableToSetError)
}
pub(crate) struct UnableToGetError;
pub(crate) async fn get_user_key_from_client_managed_state(
client: &Client,
) -> Result<SymmetricCryptoKey, UnableToGetError> {
info!("Getting the user-key from client managed-state in SDK");
let user_key_state = client
.platform()
.state()
.get::<key_management::UserKeyState>()
.map_err(|_| UnableToGetError)?
.get(USER_KEY_REPOSITORY_KEY.to_string())
.await
.map_err(|_| UnableToGetError)?
.ok_or(UnableToGetError)?;
SymmetricCryptoKey::try_from(user_key_state.decrypted_user_key).map_err(|_| UnableToGetError)
}