mirror of
https://github.com/bitwarden/browser
synced 2026-02-13 06:54:07 +00:00
107 lines
3.6 KiB
Rust
107 lines
3.6 KiB
Rust
#[napi]
|
|
pub mod ipc {
|
|
use desktop_core::ipc::server::{Message, MessageType};
|
|
use napi::threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode};
|
|
|
|
#[napi(object)]
|
|
pub struct IpcMessage {
|
|
pub client_id: u32,
|
|
pub kind: IpcMessageType,
|
|
pub message: Option<String>,
|
|
}
|
|
|
|
impl From<Message> for IpcMessage {
|
|
fn from(message: Message) -> Self {
|
|
IpcMessage {
|
|
client_id: message.client_id,
|
|
kind: message.kind.into(),
|
|
message: message.message,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[napi]
|
|
pub enum IpcMessageType {
|
|
Connected,
|
|
Disconnected,
|
|
Message,
|
|
}
|
|
|
|
impl From<MessageType> for IpcMessageType {
|
|
fn from(message_type: MessageType) -> Self {
|
|
match message_type {
|
|
MessageType::Connected => IpcMessageType::Connected,
|
|
MessageType::Disconnected => IpcMessageType::Disconnected,
|
|
MessageType::Message => IpcMessageType::Message,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[napi]
|
|
pub struct NativeIpcServer {
|
|
server: desktop_core::ipc::server::Server,
|
|
}
|
|
|
|
#[napi]
|
|
impl NativeIpcServer {
|
|
/// Create and start the IPC server without blocking.
|
|
///
|
|
/// @param name The endpoint name to listen on. This name uniquely identifies the IPC
|
|
/// connection and must be the same for both the server and client. @param callback
|
|
/// This function will be called whenever a message is received from a client.
|
|
#[allow(clippy::unused_async)] // FIXME: Remove unused async!
|
|
#[napi(factory)]
|
|
pub async fn listen(
|
|
name: String,
|
|
#[napi(ts_arg_type = "(error: null | Error, message: IpcMessage) => void")]
|
|
callback: ThreadsafeFunction<IpcMessage>,
|
|
) -> napi::Result<Self> {
|
|
let (send, mut recv) = tokio::sync::mpsc::channel::<Message>(32);
|
|
tokio::spawn(async move {
|
|
while let Some(message) = recv.recv().await {
|
|
callback.call(Ok(message.into()), ThreadsafeFunctionCallMode::NonBlocking);
|
|
}
|
|
});
|
|
|
|
let path = desktop_core::ipc::path(&name);
|
|
|
|
let server = desktop_core::ipc::server::Server::start(&path, send).map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Error listening to server - Path: {path:?} - Error: {e} - {e:?}"
|
|
))
|
|
})?;
|
|
|
|
Ok(NativeIpcServer { server })
|
|
}
|
|
|
|
/// Return the path to the IPC server.
|
|
#[napi]
|
|
pub fn get_path(&self) -> String {
|
|
self.server.path.to_string_lossy().to_string()
|
|
}
|
|
|
|
/// Stop the IPC server.
|
|
#[napi]
|
|
pub fn stop(&self) -> napi::Result<()> {
|
|
self.server.stop();
|
|
Ok(())
|
|
}
|
|
|
|
/// Send a message over the IPC server to all the connected clients
|
|
///
|
|
/// @return The number of clients that the message was sent to. Note that the number of
|
|
/// messages actually received may be less, as some clients could disconnect before
|
|
/// receiving the message.
|
|
#[napi]
|
|
pub fn send(&self, message: String) -> napi::Result<u32> {
|
|
self.server
|
|
.send(message)
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!("Error sending message - Error: {e} - {e:?}"))
|
|
})
|
|
// NAPI doesn't support u64 or usize, so we need to convert to u32
|
|
.map(|u| u32::try_from(u).unwrap_or_default())
|
|
}
|
|
}
|
|
}
|