move re-hide to main request handler

This commit is contained in:
Joseph Montanaro 2022-12-21 16:04:12 -08:00
parent 5ffa55c03c
commit bf4c46238e
6 changed files with 51 additions and 33 deletions

View File

@ -1,8 +1,5 @@
use core::time::Duration;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use tauri::State; use tauri::State;
use tokio::time::sleep;
use crate::clientinfo::Client; use crate::clientinfo::Client;
use crate::state::{AppState, Session, Credentials}; use crate::state::{AppState, Session, Credentials};
@ -30,20 +27,9 @@ pub enum Approval {
#[tauri::command] #[tauri::command]
pub fn respond( pub fn respond(response: RequestResponse, app_state: State<'_, AppState>) -> Result<(), String> {
response: RequestResponse,
window: tauri::Window,
app_state: State<'_, AppState>
) -> Result<(), String> {
app_state.send_response(response) app_state.send_response(response)
.map_err(|e| format!("Error responding to request: {e}"))?; .map_err(|e| format!("Error responding to request: {e}"))
tauri::async_runtime::spawn(async move {
sleep(Duration::from_secs(3)).await;
let _ = window.hide();
});
Ok(())
} }
@ -74,5 +60,5 @@ pub async fn save_credentials(
) -> Result<(), String> { ) -> Result<(), String> {
app_state.save_creds(credentials, &passphrase) app_state.save_creds(credentials, &passphrase)
.await .await
.map_err(|e| e.to_string()) .map_err(|e| {eprintln!("{e:?}"); e.to_string()})
} }

View File

@ -1,8 +1,10 @@
use core::time::Duration;
use std::io; use std::io;
use std::net::{SocketAddr, SocketAddrV4}; use std::net::{SocketAddr, SocketAddrV4};
use tokio::net::{TcpListener, TcpStream}; use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::sync::oneshot; use tokio::sync::oneshot;
use tokio::time::sleep;
use tauri::{AppHandle, Manager}; use tauri::{AppHandle, Manager};
@ -49,7 +51,8 @@ impl Handler {
} }
let req = Request {id: self.request_id, clients}; let req = Request {id: self.request_id, clients};
self.notify_frontend(&req).await?; self.app.emit_all("credentials-request", &req)?;
let starting_visibility = self.ensure_visible()?;
match self.wait_for_response().await? { match self.wait_for_response().await? {
Approval::Approved => self.send_credentials().await?, Approval::Approved => self.send_credentials().await?,
@ -61,6 +64,17 @@ impl Handler {
} }
} }
// only hide the window if a) it was hidden to start with
// and b) there are no other pending requests
let state = self.app.state::<AppState>();
if !starting_visibility && state.req_count() == 0 {
let handle = self.app.app_handle();
tauri::async_runtime::spawn(async move {
sleep(Duration::from_secs(3)).await;
let _ = handle.get_window("main").map(|w| w.hide());
});
}
Ok(()) Ok(())
} }
@ -90,15 +104,15 @@ impl Handler {
clients.iter().any(|c| state.is_banned(c)) clients.iter().any(|c| state.is_banned(c))
} }
async fn notify_frontend(&self, req: &Request) -> Result<(), RequestError> { fn ensure_visible(&self) -> Result<bool, RequestError> {
self.app.emit_all("credentials-request", req)?;
let window = self.app.get_window("main").ok_or(RequestError::NoMainWindow)?; let window = self.app.get_window("main").ok_or(RequestError::NoMainWindow)?;
if !window.is_visible()? { let starting_visibility = window.is_visible()?;
if !starting_visibility {
window.unminimize()?; window.unminimize()?;
window.show()?; window.show()?;
} }
window.set_focus()?; window.set_focus()?;
Ok(()) Ok(starting_visibility)
} }
async fn wait_for_response(&mut self) -> Result<Approval, RequestError> { async fn wait_for_response(&mut self) -> Result<Approval, RequestError> {

View File

@ -65,8 +65,10 @@ pub struct AppState {
impl AppState { impl AppState {
pub fn new() -> Result<Self, SetupError> { pub fn new() -> Result<Self, SetupError> {
let conf = AppConfig::default();
let conn_opts = SqliteConnectOptions::new() let conn_opts = SqliteConnectOptions::new()
.filename("creddy.db") .filename(&conf.db_path)
.create_if_missing(true); .create_if_missing(true);
let pool_opts = SqlitePoolOptions::new(); let pool_opts = SqlitePoolOptions::new();
@ -75,7 +77,7 @@ impl AppState {
let creds = runtime::block_on(Self::load_creds(&pool))?; let creds = runtime::block_on(Self::load_creds(&pool))?;
let state = AppState { let state = AppState {
config: RwLock::new(AppConfig::default()), config: RwLock::new(conf),
session: RwLock::new(creds), session: RwLock::new(creds),
request_count: RwLock::new(0), request_count: RwLock::new(0),
open_requests: RwLock::new(HashMap::new()), open_requests: RwLock::new(HashMap::new()),
@ -161,6 +163,11 @@ impl AppState {
open_requests.remove(&id); open_requests.remove(&id);
} }
pub fn req_count(&self) -> usize {
let open_requests = self.open_requests.read().unwrap();
open_requests.len()
}
pub fn send_response(&self, response: ipc::RequestResponse) -> Result<(), SendResponseError> { pub fn send_response(&self, response: ipc::RequestResponse) -> Result<(), SendResponseError> {
let mut open_requests = self.open_requests.write().unwrap(); let mut open_requests = self.open_requests.write().unwrap();
let chan = open_requests let chan = open_requests

View File

@ -5,13 +5,15 @@
export let appState; export let appState;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
let error = null;
let AccessKeyId, SecretAccessKey, passphrase let AccessKeyId, SecretAccessKey, passphrase
async function save() { async function save() {
try { try {
console.log('Saving credentials.'); console.log('Saving credentials.');
let credentials = {AccessKeyId, SecretAccessKey}; let credentials = {AccessKeyId, SecretAccessKey};
console.log(credentials);
try {
await invoke('save_credentials', {credentials, passphrase}); await invoke('save_credentials', {credentials, passphrase});
if (appState.currentRequest) { if (appState.currentRequest) {
dispatch('navigate', {target: 'ShowApproved'}) dispatch('navigate', {target: 'ShowApproved'})
@ -20,22 +22,30 @@
dispatch('navigate', {target: 'Home'}) dispatch('navigate', {target: 'Home'})
} }
} }
catch (e) {
error = e;
}
}
catch (e) { catch (e) {
console.log("Error saving credentials:", e); console.log("Error saving credentials:", e);
} }
} }
</script> </script>
{#if error}
<div class="text-red-400">{error}</div>
{/if}
<form action="#" on:submit|preventDefault="{save}"> <form action="#" on:submit|preventDefault="{save}">
<div class="text-gray-200">AWS Access Key ID</div> <div class="text-gray-200">AWS Access Key ID</div>
<input class="text-gray-200 bg-zinc-800" type="text" bind:value="{AccessKeyId}" /> <input class="text-gray-200 bg-zinc-800" type="text" bind:value="{AccessKeyId}" />
<div class="text-gray-200">AWS Secret Access Key</div> <div class="text-gray-200">AWS Secret Access Key</div>
<input class="text-gray-200 bg-zinc-800" type="text" bind:value="{SecretAccessKey}" /> <input class="text-gray-200 bg-zinc-800" type="password" bind:value="{SecretAccessKey}" />
<div class="text-gray-200">Passphrase</div> <div class="text-gray-200">Passphrase</div>
<input class="text-gray-200 bg-zinc-800" type="text" bind:value="{passphrase}" /> <input class="text-gray-200 bg-zinc-800" type="password" bind:value="{passphrase}" />
<input class="text-gray-200" type="submit" /> <input class="text-gray-200" type="submit" />
</form> </form>

View File

@ -28,7 +28,7 @@
</script> </script>
{#if error} {#if error}
<div class="text-red-400">Error attempting to send approval: {error}</div> <div class="text-red-400">{error}</div>
{:else} {:else}
<h1 class="text-4xl text-gray-300">Approved!</h1> <h1 class="text-4xl text-gray-300">Approved!</h1>
{/if} {/if}

View File

@ -30,6 +30,7 @@
{#if error} {#if error}
<div class="text-red-400">{error}</div> <div class="text-red-400">{error}</div>
{/if} {/if}
<form action="#" on:submit|preventDefault="{unlock}"> <form action="#" on:submit|preventDefault="{unlock}">
<div class="text-gray-200">Enter your passphrase:</div> <div class="text-gray-200">Enter your passphrase:</div>
<input autofocus class="text-gray-200 bg-zinc-800" type="password" placeholder="correct horse battery staple" bind:value="{passphrase}" /> <input autofocus class="text-gray-200 bg-zinc-800" type="password" placeholder="correct horse battery staple" bind:value="{passphrase}" />