tauri_plugin_secure_element/
lib.rs

1use tauri::{
2    plugin::{Builder, TauriPlugin},
3    Manager, Runtime,
4};
5
6pub use models::*;
7
8#[cfg(desktop)]
9mod desktop;
10#[cfg(mobile)]
11mod mobile;
12
13mod commands;
14mod error;
15mod models;
16mod validation;
17
18pub use error::{Error, Result};
19
20#[cfg(desktop)]
21use desktop::SecureElement;
22#[cfg(mobile)]
23use mobile::SecureElement;
24
25// Provide a stub SecureElement for when neither desktop nor mobile is configured
26// This allows the code to compile during cargo package
27#[cfg(not(any(desktop, mobile)))]
28mod stub {
29    use tauri::{AppHandle, Runtime};
30    use crate::models::*;
31    use crate::Result;
32    
33    pub struct SecureElement<R: Runtime>(AppHandle<R>);
34    
35    impl<R: Runtime> SecureElement<R> {
36        pub fn new(_app: AppHandle<R>) -> Self {
37            Self(_app)
38        }
39        
40        pub fn ping(&self, payload: PingRequest) -> Result<PingResponse> {
41            Ok(PingResponse { value: payload.value })
42        }
43        
44        pub fn generate_secure_key(&self, _payload: GenerateSecureKeyRequest) -> Result<GenerateSecureKeyResponse> {
45            Err(crate::Error::Io(std::io::Error::new(
46                std::io::ErrorKind::Unsupported,
47                "Secure element not available - compilation stub",
48            )))
49        }
50        
51        pub fn list_keys(&self, _payload: ListKeysRequest) -> Result<ListKeysResponse> {
52            Err(crate::Error::Io(std::io::Error::new(
53                std::io::ErrorKind::Unsupported,
54                "Secure element not available - compilation stub",
55            )))
56        }
57        
58        pub fn sign_with_key(&self, _payload: SignWithKeyRequest) -> Result<SignWithKeyResponse> {
59            Err(crate::Error::Io(std::io::Error::new(
60                std::io::ErrorKind::Unsupported,
61                "Secure element not available - compilation stub",
62            )))
63        }
64        
65        pub fn delete_key(&self, _payload: DeleteKeyRequest) -> Result<DeleteKeyResponse> {
66            Err(crate::Error::Io(std::io::Error::new(
67                std::io::ErrorKind::Unsupported,
68                "Secure element not available - compilation stub",
69            )))
70        }
71        
72        pub fn check_secure_element_support(&self) -> Result<CheckSecureElementSupportResponse> {
73            Err(crate::Error::Io(std::io::Error::new(
74                std::io::ErrorKind::Unsupported,
75                "Secure element not available - compilation stub",
76            )))
77        }
78    }
79}
80
81#[cfg(not(any(desktop, mobile)))]
82use stub::SecureElement;
83
84/// Extensions to [`tauri::App`], [`tauri::AppHandle`] and [`tauri::Window`] to access the secure-element APIs.
85pub trait SecureElementExt<R: Runtime> {
86    fn secure_element(&self) -> &SecureElement<R>;
87}
88
89#[cfg(any(desktop, mobile))]
90impl<R: Runtime, T: Manager<R>> crate::SecureElementExt<R> for T {
91    fn secure_element(&self) -> &SecureElement<R> {
92        self.state::<SecureElement<R>>().inner()
93    }
94}
95
96#[cfg(not(any(desktop, mobile)))]
97impl<R: Runtime, T: Manager<R>> crate::SecureElementExt<R> for T {
98    fn secure_element(&self) -> &SecureElement<R> {
99        // This should never be called during actual use, only for compilation
100        panic!("SecureElement is not available - this is a compilation stub")
101    }
102}
103
104/// Initializes the plugin.
105pub fn init<R: Runtime>() -> TauriPlugin<R> {
106    Builder::new("secure-element")
107        .invoke_handler(tauri::generate_handler![
108            commands::ping,
109            commands::generate_secure_key,
110            commands::list_keys,
111            commands::sign_with_key,
112            commands::delete_key,
113            commands::check_secure_element_support
114        ])
115        .setup(|app, api| {
116            #[cfg(mobile)]
117            {
118                let secure_element = mobile::init(app, api)?;
119                app.manage(secure_element);
120            }
121            #[cfg(desktop)]
122            {
123                let secure_element = desktop::init(app, api)?;
124                app.manage(secure_element);
125            }
126            #[cfg(not(any(desktop, mobile)))]
127            {
128                // Stub for compilation during cargo package
129                let _ = api;
130                let secure_element = SecureElement::new(app.clone());
131                app.manage(secure_element);
132            }
133            Ok(())
134        })
135        .build()
136}