Skip to main content

tauri_plugin_biometric/
lib.rs

1// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
2// SPDX-License-Identifier: Apache-2.0
3// SPDX-License-Identifier: MIT
4
5//! Prompt the user for biometric authentication.
6//!
7//! - Supported platforms: Android and iOS.
8
9#![cfg(mobile)]
10
11use serde::Serialize;
12use tauri::{
13    Manager, Runtime,
14    plugin::{Builder, PluginHandle, TauriPlugin},
15};
16
17pub use models::*;
18
19mod error;
20mod models;
21
22pub use error::{Error, Result};
23
24#[cfg(target_os = "android")]
25const PLUGIN_IDENTIFIER: &str = "app.tauri.biometric";
26
27#[cfg(target_os = "ios")]
28tauri::ios_plugin_binding!(init_plugin_biometric);
29
30/// Access to the biometric APIs.
31pub struct Biometric<R: Runtime>(PluginHandle<R>);
32
33#[derive(Serialize)]
34struct AuthenticatePayload {
35    reason: String,
36    #[serde(flatten)]
37    options: AuthOptions,
38}
39
40impl<R: Runtime> Biometric<R> {
41    /// Checks the device's availability and type of biometric authentication, as reported by the
42    /// operating system. Errors if the underlying mobile plugin invocation fails.
43    pub fn status(&self) -> crate::Result<Status> {
44        self.0.run_mobile_plugin("status", ()).map_err(Into::into)
45    }
46
47    /// Prompts the user for biometric authentication using the system UI (Android
48    /// `BiometricPrompt` or iOS `LocalAuthentication`), showing `reason` as the purpose of the
49    /// request. Resolves once the user is authenticated and errors if authentication fails, is
50    /// canceled, or the underlying mobile plugin invocation fails.
51    pub fn authenticate(&self, reason: String, options: AuthOptions) -> crate::Result<()> {
52        self.0
53            .run_mobile_plugin("authenticate", AuthenticatePayload { reason, options })
54            .map_err(Into::into)
55    }
56}
57
58/// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the biometric APIs.
59pub trait BiometricExt<R: Runtime> {
60    /// Returns the [`Biometric`] instance managed by the app.
61    fn biometric(&self) -> &Biometric<R>;
62}
63
64impl<R: Runtime, T: Manager<R>> crate::BiometricExt<R> for T {
65    fn biometric(&self) -> &Biometric<R> {
66        self.state::<Biometric<R>>().inner()
67    }
68}
69
70/// Initializes the plugin.
71pub fn init<R: Runtime>() -> TauriPlugin<R> {
72    Builder::new("biometric")
73        .setup(|app, api| {
74            #[cfg(target_os = "android")]
75            let handle = api.register_android_plugin(PLUGIN_IDENTIFIER, "BiometricPlugin")?;
76            #[cfg(target_os = "ios")]
77            let handle = api.register_ios_plugin(init_plugin_biometric)?;
78            app.manage(Biometric(handle));
79            Ok(())
80        })
81        .build()
82}