1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-26 17:43:22 +00:00
Files
browser/apps/desktop/desktop_native/napi/src/biometrics.rs
2026-02-02 14:13:17 -05:00

101 lines
3.1 KiB
Rust

#[napi]
pub mod biometrics {
use desktop_core::biometric::{Biometric, BiometricTrait};
// Prompt for biometric confirmation
#[napi]
pub async fn prompt(
hwnd: napi::bindgen_prelude::Buffer,
message: String,
) -> napi::Result<bool> {
Biometric::prompt(hwnd.into(), message)
.await
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
#[napi]
pub async fn available() -> napi::Result<bool> {
Biometric::available()
.await
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
#[napi]
pub async fn set_biometric_secret(
service: String,
account: String,
secret: String,
key_material: Option<KeyMaterial>,
iv_b64: String,
) -> napi::Result<String> {
Biometric::set_biometric_secret(
&service,
&account,
&secret,
key_material.map(|m| m.into()),
&iv_b64,
)
.await
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
/// Retrieves the biometric secret for the given service and account.
/// Throws Error with message [`passwords::PASSWORD_NOT_FOUND`] if the secret does not exist.
#[napi]
pub async fn get_biometric_secret(
service: String,
account: String,
key_material: Option<KeyMaterial>,
) -> napi::Result<String> {
Biometric::get_biometric_secret(&service, &account, key_material.map(|m| m.into()))
.await
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
/// Derives key material from biometric data. Returns a string encoded with a
/// base64 encoded key and the base64 encoded challenge used to create it
/// separated by a `|` character.
///
/// If the iv is provided, it will be used as the challenge. Otherwise a random challenge will
/// be generated.
///
/// `format!("<key_base64>|<iv_base64>")`
#[allow(clippy::unused_async)] // FIXME: Remove unused async!
#[napi]
pub async fn derive_key_material(iv: Option<String>) -> napi::Result<OsDerivedKey> {
Biometric::derive_key_material(iv.as_deref())
.map(|k| k.into())
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
#[napi(object)]
pub struct KeyMaterial {
pub os_key_part_b64: String,
pub client_key_part_b64: Option<String>,
}
impl From<KeyMaterial> for desktop_core::biometric::KeyMaterial {
fn from(km: KeyMaterial) -> Self {
desktop_core::biometric::KeyMaterial {
os_key_part_b64: km.os_key_part_b64,
client_key_part_b64: km.client_key_part_b64,
}
}
}
#[napi(object)]
pub struct OsDerivedKey {
pub key_b64: String,
pub iv_b64: String,
}
impl From<desktop_core::biometric::OsDerivedKey> for OsDerivedKey {
fn from(km: desktop_core::biometric::OsDerivedKey) -> Self {
OsDerivedKey {
key_b64: km.key_b64,
iv_b64: km.iv_b64,
}
}
}
}