mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 17:23:37 +00:00
[BEEEP] [EC-141] Rust - Windows hello (#2635)
This commit is contained in:
9
apps/desktop/desktop_native/src/biometric/macos.rs
Normal file
9
apps/desktop/desktop_native/src/biometric/macos.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
pub fn prompt(_hwnd: Vec<u8>, _message: String) -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
||||
|
||||
pub fn available() -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
||||
5
apps/desktop/desktop_native/src/biometric/mod.rs
Normal file
5
apps/desktop/desktop_native/src/biometric/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
#[cfg_attr(target_os = "linux", path = "unix.rs")]
|
||||
#[cfg_attr(target_os = "windows", path = "windows.rs")]
|
||||
#[cfg_attr(target_os = "macos", path = "macos.rs")]
|
||||
mod biometric;
|
||||
pub use biometric::*;
|
||||
9
apps/desktop/desktop_native/src/biometric/unix.rs
Normal file
9
apps/desktop/desktop_native/src/biometric/unix.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
pub fn prompt(_hwnd: Vec<u8>, _message: String) -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
||||
|
||||
pub fn available() -> Result<bool> {
|
||||
bail!("platform not supported");
|
||||
}
|
||||
51
apps/desktop/desktop_native/src/biometric/windows.rs
Normal file
51
apps/desktop/desktop_native/src/biometric/windows.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use anyhow::Result;
|
||||
use windows::{
|
||||
core::factory, Foundation::IAsyncOperation, Security::Credentials::UI::*,
|
||||
Win32::Foundation::HWND, Win32::System::WinRT::IUserConsentVerifierInterop,
|
||||
};
|
||||
|
||||
pub fn prompt(hwnd: Vec<u8>, message: String) -> Result<bool> {
|
||||
let interop = factory::<UserConsentVerifier, IUserConsentVerifierInterop>()?;
|
||||
|
||||
let h = isize::from_le_bytes(hwnd.try_into().unwrap());
|
||||
let window = HWND(h);
|
||||
|
||||
let operation: IAsyncOperation<UserConsentVerificationResult> =
|
||||
unsafe { interop.RequestVerificationForWindowAsync(window, message)? };
|
||||
|
||||
let result: UserConsentVerificationResult = operation.get()?;
|
||||
|
||||
match result {
|
||||
UserConsentVerificationResult::Verified => Ok(true),
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn available() -> Result<bool> {
|
||||
let ucv_available = UserConsentVerifier::CheckAvailabilityAsync()?.get()?;
|
||||
|
||||
match ucv_available {
|
||||
UserConsentVerifierAvailability::Available => Ok(true),
|
||||
UserConsentVerifierAvailability::DeviceBusy => Ok(true), // TODO: Look into removing this and making the check more ad-hoc
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_prompt() {
|
||||
prompt(
|
||||
vec![0, 0, 0, 0, 0, 0, 0, 0],
|
||||
String::from("Hello from Rust"),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_available() {
|
||||
assert!(available().unwrap())
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#[macro_use]
|
||||
extern crate napi_derive;
|
||||
|
||||
mod biometric;
|
||||
mod password;
|
||||
|
||||
#[napi]
|
||||
@@ -37,3 +38,21 @@ pub mod passwords {
|
||||
.map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub mod biometrics {
|
||||
// Prompt for biometric confirmation
|
||||
#[napi]
|
||||
pub async fn prompt(
|
||||
hwnd: napi::bindgen_prelude::Buffer,
|
||||
message: String,
|
||||
) -> napi::Result<bool> {
|
||||
super::biometric::prompt(hwnd.into(), message)
|
||||
.map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub async fn available() -> napi::Result<bool> {
|
||||
super::biometric::available().map_err(|e| napi::Error::from_reason(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user