chore(agent): major version dependency bump (#4446)
This commit is contained in:
@@ -40,6 +40,8 @@ pub enum AppError {
|
||||
RegistrationInsertError,
|
||||
#[error("Failed to save registrations to store")]
|
||||
RegistrationSaveError,
|
||||
#[error("Store error: {0}")]
|
||||
TauriPluginStore(#[from] tauri_plugin_store::Error),
|
||||
}
|
||||
|
||||
impl IntoResponse for AppError {
|
||||
|
||||
@@ -4,20 +4,20 @@ use chrono::{DateTime, Utc};
|
||||
use dashmap::DashMap;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use tauri_plugin_store::StoreBuilder;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::error::AppError;
|
||||
|
||||
/// Describes one registered app instance
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Registration {
|
||||
pub registered_at: DateTime<Utc>,
|
||||
pub registered_at: DateTime<Utc>,
|
||||
|
||||
/// base16 (lowercase) encoded shared secret that the client
|
||||
/// and agent established during registration that is used
|
||||
/// to encrypt traffic between them
|
||||
pub shared_secret_b16: String
|
||||
/// base16 (lowercase) encoded shared secret that the client
|
||||
/// and agent established during registration that is used
|
||||
/// to encrypt traffic between them
|
||||
pub shared_secret_b16: String,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -30,28 +30,26 @@ pub struct AppState {
|
||||
|
||||
/// Registrations against the agent, the key is the auth
|
||||
/// token associated to the registration
|
||||
registrations: DashMap<String, Registration>
|
||||
registrations: DashMap<String, Registration>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
|
||||
pub fn new(app_handle: tauri::AppHandle) -> Self {
|
||||
let mut store = StoreBuilder::new("app_data.bin")
|
||||
.build(app_handle);
|
||||
let store = StoreBuilder::new(&app_handle, "app_data.bin").build();
|
||||
|
||||
let _ = store.load();
|
||||
|
||||
// Try loading and parsing registrations from the store, if that failed,
|
||||
// load the default list
|
||||
let registrations = store.get("registrations")
|
||||
.and_then(|val| serde_json::from_value(val.clone()).ok())
|
||||
.unwrap_or_else(|| DashMap::new());
|
||||
|
||||
let registrations = store
|
||||
.get("registrations")
|
||||
.and_then(|val| serde_json::from_value(val.clone()).ok())
|
||||
.unwrap_or_else(|| DashMap::new());
|
||||
|
||||
Self {
|
||||
active_registration_code: RwLock::new(None),
|
||||
cancellation_tokens: DashMap::new(),
|
||||
registrations
|
||||
registrations,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,39 +58,41 @@ impl AppState {
|
||||
/// reference, you shouldn't do it for registrations as `update_registrations`
|
||||
/// performs save operation that needs to be done and should be used instead
|
||||
pub fn get_registrations(&self) -> &DashMap<String, Registration> {
|
||||
&self.registrations
|
||||
&self.registrations
|
||||
}
|
||||
|
||||
/// Provides you an opportunity to update the registrations list
|
||||
/// and also persists the data to the disk
|
||||
pub fn update_registrations(
|
||||
pub fn update_registrations(
|
||||
&self,
|
||||
app_handle: tauri::AppHandle,
|
||||
update_func: impl FnOnce(&DashMap<String, Registration>)
|
||||
update_func: impl FnOnce(&DashMap<String, Registration>),
|
||||
) -> Result<(), AppError> {
|
||||
update_func(&self.registrations);
|
||||
|
||||
let mut store = StoreBuilder::new("app_data.bin")
|
||||
.build(app_handle);
|
||||
let store = StoreBuilder::new(&app_handle, "app_data.bin").build();
|
||||
|
||||
let _ = store.load();
|
||||
let _ = store.load()?;
|
||||
|
||||
store.delete("registrations")
|
||||
.map_err(|_| AppError::RegistrationClearError)?;
|
||||
let _ = store
|
||||
.delete("registrations")
|
||||
.then_some(())
|
||||
.ok_or(AppError::RegistrationClearError)?;
|
||||
|
||||
store.insert("registrations".into(), serde_json::to_value(self.registrations.clone()).unwrap())
|
||||
.map_err(|_| AppError::RegistrationInsertError)?;
|
||||
let _ = store.set(
|
||||
"registrations",
|
||||
serde_json::to_value(self.registrations.clone()).unwrap(),
|
||||
);
|
||||
|
||||
store.save()
|
||||
.map_err(|_| AppError::RegistrationSaveError)?;
|
||||
store.save().map_err(|_| AppError::RegistrationSaveError)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn validate_registration(&self, registration: &str) -> bool {
|
||||
match *self.active_registration_code.read().await {
|
||||
Some(ref code) => code == registration,
|
||||
None => false
|
||||
Some(ref code) => code == registration,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,50 +105,40 @@ impl AppState {
|
||||
}
|
||||
|
||||
pub fn validate_access(&self, auth_key: &str) -> bool {
|
||||
self.registrations.get(auth_key).is_some()
|
||||
self.registrations.get(auth_key).is_some()
|
||||
}
|
||||
|
||||
pub fn validate_access_and_get_data<T>(
|
||||
&self,
|
||||
auth_key: &str,
|
||||
nonce: &str,
|
||||
data: &Bytes
|
||||
&self,
|
||||
auth_key: &str,
|
||||
nonce: &str,
|
||||
data: &Bytes,
|
||||
) -> Option<T>
|
||||
where
|
||||
T : DeserializeOwned
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
if let Some(registration) = self.registrations.get(auth_key) {
|
||||
let key: [u8; 32] = base16::decode(®istration.shared_secret_b16)
|
||||
.ok()?
|
||||
[0..32]
|
||||
.try_into()
|
||||
.ok()?;
|
||||
if let Some(registration) = self.registrations.get(auth_key) {
|
||||
let key: [u8; 32] = base16::decode(®istration.shared_secret_b16).ok()?[0..32]
|
||||
.try_into()
|
||||
.ok()?;
|
||||
|
||||
let nonce: [u8; 12] = base16::decode(nonce)
|
||||
.ok()?
|
||||
[0..12]
|
||||
.try_into()
|
||||
.ok()?;
|
||||
let nonce: [u8; 12] = base16::decode(nonce).ok()?[0..12].try_into().ok()?;
|
||||
|
||||
let cipher = Aes256Gcm::new(&key.into());
|
||||
let cipher = Aes256Gcm::new(&key.into());
|
||||
|
||||
let data = data
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect::<Vec<u8>>();
|
||||
let data = data.iter().cloned().collect::<Vec<u8>>();
|
||||
|
||||
let plain_data = cipher.decrypt(&nonce.into(), data.as_slice())
|
||||
.ok()?;
|
||||
let plain_data = cipher.decrypt(&nonce.into(), data.as_slice()).ok()?;
|
||||
|
||||
serde_json::from_reader(plain_data.as_slice())
|
||||
.ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
serde_json::from_reader(plain_data.as_slice()).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_registration_info(&self, auth_key: &str) -> Option<Registration> {
|
||||
self.registrations.get(auth_key)
|
||||
.map(|reference| reference.value().clone())
|
||||
self.registrations
|
||||
.get(auth_key)
|
||||
.map(|reference| reference.value().clone())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,39 @@
|
||||
#[cfg(desktop)]
|
||||
pub async fn check_and_install_updates(app: tauri::AppHandle, updater: tauri_plugin_updater::Updater) {
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_dialog::MessageDialogKind;
|
||||
use tauri_plugin_dialog::DialogExt;
|
||||
pub async fn check_and_install_updates(
|
||||
app: tauri::AppHandle,
|
||||
updater: tauri_plugin_updater::Updater,
|
||||
) {
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_dialog::DialogExt;
|
||||
use tauri_plugin_dialog::MessageDialogButtons;
|
||||
use tauri_plugin_dialog::MessageDialogKind;
|
||||
|
||||
let update = updater.check().await;
|
||||
|
||||
let update = updater.check().await;
|
||||
if let Ok(Some(update)) = update {
|
||||
let do_update = app
|
||||
.dialog()
|
||||
.message(format!(
|
||||
"Update to {} is available!{}",
|
||||
update.version,
|
||||
update
|
||||
.body
|
||||
.clone()
|
||||
.map(|body| format!("\n\nRelease Notes: {}", body))
|
||||
.unwrap_or("".into())
|
||||
))
|
||||
.title("Update Available")
|
||||
.kind(MessageDialogKind::Info)
|
||||
.buttons(MessageDialogButtons::OkCancelCustom(
|
||||
"Update".to_string(),
|
||||
"Cancel".to_string(),
|
||||
))
|
||||
.blocking_show();
|
||||
|
||||
if let Ok(Some(update)) = update {
|
||||
let do_update = app.dialog()
|
||||
.message(
|
||||
format!(
|
||||
"Update to {} is available!{}",
|
||||
update.version,
|
||||
update.body
|
||||
.clone()
|
||||
.map(|body| format!("\n\nRelease Notes: {}", body))
|
||||
.unwrap_or("".into())
|
||||
)
|
||||
)
|
||||
.title("Update Available")
|
||||
.kind(MessageDialogKind::Info)
|
||||
.ok_button_label("Update")
|
||||
.cancel_button_label("Cancel")
|
||||
.blocking_show();
|
||||
if do_update {
|
||||
let _ = update.download_and_install(|_, _| {}, || {}).await;
|
||||
|
||||
if do_update {
|
||||
let _ = update.download_and_install(|_, _| {}, || {}).await;
|
||||
|
||||
tauri::process::restart(&app.env());
|
||||
}
|
||||
}
|
||||
tauri::process::restart(&app.env());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user