From ea4ac3326a22b81007e77b9f634421950d18c166 Mon Sep 17 00:00:00 2001 From: Apokalip Date: Mon, 6 Feb 2023 08:08:25 +0200 Subject: [PATCH 1/7] Fix authorization Signed-off-by: Apokalip --- src/service.rs | 4 +++- ui/src-tauri/src/main.rs | 15 ++++++++------- ui/src/App.js | 7 ++++++- ui/src/pages/Authorize.js | 10 +++++----- ui/src/pages/ViewPhrase/ViewPhrasePage.js | 4 ++-- ui/src/pages/ViewPhrase/ViewSecretPhrase.js | 3 ++- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/service.rs b/src/service.rs index d51e0942..03cc20b7 100644 --- a/src/service.rs +++ b/src/service.rs @@ -212,9 +212,12 @@ where .is_ok() { self.authorizer.sleep().await; + println!("Password is ok"); return Ok(()); } } else { + println!("Password is now known, returning auth error"); + self.authorizer.sleep().await; return Err(Error::AuthorizationError); } delay_password_retry().await; @@ -445,7 +448,6 @@ where #[inline] pub async fn cancel_signing(&mut self) { self.state.lock().currently_signing = false; - // Forcefully sleep because the authorizer gets stuck awake if we exit recovery window self.authorizer.lock().await.authorizer.sleep(); } diff --git a/ui/src-tauri/src/main.rs b/ui/src-tauri/src/main.rs index 6eb75482..7db4418d 100644 --- a/ui/src-tauri/src/main.rs +++ b/ui/src-tauri/src/main.rs @@ -267,6 +267,7 @@ impl Authorizer for User { T: Serialize, { APP_STATE.set_authorizing(true); + println!("INFO: Server Awake"); self.emit("authorize", prompt); Box::pin(async move {}) } @@ -274,6 +275,7 @@ impl Authorizer for User { #[inline] fn sleep(&mut self) -> UnitFuture { APP_STATE.set_authorizing(false); + println!("INFO: Server Sleeping"); self.emit("abort_auth", &()); Box::pin(async move { self.validate_password().await }) } @@ -569,11 +571,10 @@ async fn get_recovery_phrase( server_store: State<'_, ServerStore>, ) -> Result { if let Some(store) = &mut *server_store.lock().await { - let mnemonic = store - .get_stored_mnemonic(Network::Dolphin, &prompt) - .await - .expect("Unable to fetch mnemonic"); - Ok(mnemonic) + match store.get_stored_mnemonic(Network::Dolphin, &prompt).await { + Ok(mnemonic) => Ok(mnemonic), + Err(_) => Err(()) + } } else { Err(()) } @@ -713,10 +714,10 @@ fn main() { "about" => window(app, "about").hide().expect("Unable to hide window."), "main" => { if APP_STATE.get_ready() { - window(app, "main").hide().expect("Unable to hide window."); if APP_STATE.get_authorizing() { + //window(app, "main").hide().expect("Unable to hide window."); window(app, "main") - .emit_all("abort_auth", "Aborting Authorization") + .emit("abort_auth", "Aborting Authorization") .expect("Failed to abort authorization"); } } else { diff --git a/ui/src/App.js b/ui/src/App.js index e0570561..6c3e37ca 100644 --- a/ui/src/App.js +++ b/ui/src/App.js @@ -158,6 +158,7 @@ function App() { // Case 1: we need authorization for exporting the recovery phrase. if (event.payload === GET_RECOVERY_PHRASE) { + console.log("Viewing secret phrase window"); navigate("/view-secret-phrase"); appWindow.show(); return; @@ -208,7 +209,11 @@ function App() { } console.log("[INFO]: Send request to export recovery phrase."); - let phrase = await invoke('get_recovery_phrase', { prompt: GET_RECOVERY_PHRASE }); + let phrase = await invoke('get_recovery_phrase', { prompt: GET_RECOVERY_PHRASE }) + .catch(error => { + console.log("Failed getting mnemonic, either fail or abort(expected)"); + return + }); if (phrase) { setExportedSecretPhrase(phrase); diff --git a/ui/src/pages/Authorize.js b/ui/src/pages/Authorize.js index 0bb0e587..5be06e55 100644 --- a/ui/src/pages/Authorize.js +++ b/ui/src/pages/Authorize.js @@ -13,11 +13,11 @@ const Authorize = ({ const [passwordInvalid, setPasswordInvalid] = useState(false); - useEffect(() => { - once("abort_auth", async () => { - await onClickDecline(); - }); - }); + // useEffect(() => { + // once("abort_auth", async () => { + // await onClickDecline(); + // }); + // }); const onClickAuthorize = async () => { console.log("[INFO]: Authorizing."); diff --git a/ui/src/pages/ViewPhrase/ViewPhrasePage.js b/ui/src/pages/ViewPhrase/ViewPhrasePage.js index 7223ddad..30d38756 100644 --- a/ui/src/pages/ViewPhrase/ViewPhrasePage.js +++ b/ui/src/pages/ViewPhrase/ViewPhrasePage.js @@ -13,13 +13,13 @@ const ViewPhrasePage = ({ onClickSubmitPassword, onClickCancel }) => { - + useEffect(() => { once("abort_auth", async () => { await onClickCancel(); }); }); - + return (<>
diff --git a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js index 1089b1a3..8da774dc 100644 --- a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js +++ b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js @@ -1,4 +1,5 @@ -import { useState } from "react"; +import { once } from '@tauri-apps/api/event'; +import React, { useState, useEffect } from 'react'; import ViewPhrasePage from "./ViewPhrasePage"; import ViewPhraseSuccess from "./ViewPhraseSuccess"; From 725b0b96079985d694be7bb66994e37837bba8e6 Mon Sep 17 00:00:00 2001 From: Apokalip Date: Mon, 6 Feb 2023 08:19:48 +0200 Subject: [PATCH 2/7] fmt Signed-off-by: Apokalip --- ui/src-tauri/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src-tauri/src/main.rs b/ui/src-tauri/src/main.rs index 7db4418d..82fc2029 100644 --- a/ui/src-tauri/src/main.rs +++ b/ui/src-tauri/src/main.rs @@ -573,7 +573,7 @@ async fn get_recovery_phrase( if let Some(store) = &mut *server_store.lock().await { match store.get_stored_mnemonic(Network::Dolphin, &prompt).await { Ok(mnemonic) => Ok(mnemonic), - Err(_) => Err(()) + Err(_) => Err(()), } } else { Err(()) From 19c7687ef77c9e4072147953c305f8ff1176e070 Mon Sep 17 00:00:00 2001 From: Apokalip Date: Mon, 6 Feb 2023 08:28:27 +0200 Subject: [PATCH 3/7] clean up js imports Signed-off-by: Apokalip --- ui/src/pages/Authorize.js | 10 +--------- ui/src/pages/ViewPhrase/ViewSecretPhrase.js | 3 +-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/ui/src/pages/Authorize.js b/ui/src/pages/Authorize.js index 5be06e55..bd4753e5 100644 --- a/ui/src/pages/Authorize.js +++ b/ui/src/pages/Authorize.js @@ -1,5 +1,4 @@ -import { once } from '@tauri-apps/api/event'; -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { Button, Input } from 'semantic-ui-react'; const Authorize = ({ @@ -12,13 +11,6 @@ const Authorize = ({ const [password, setPassword] = useState(''); const [passwordInvalid, setPasswordInvalid] = useState(false); - - // useEffect(() => { - // once("abort_auth", async () => { - // await onClickDecline(); - // }); - // }); - const onClickAuthorize = async () => { console.log("[INFO]: Authorizing."); const shouldRetry = await sendPassword(password); diff --git a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js index 8da774dc..0b05cb79 100644 --- a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js +++ b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js @@ -1,5 +1,4 @@ -import { once } from '@tauri-apps/api/event'; -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import ViewPhrasePage from "./ViewPhrasePage"; import ViewPhraseSuccess from "./ViewPhraseSuccess"; From bbecce95425d38098ae72661b72da10b6c5252e2 Mon Sep 17 00:00:00 2001 From: Apokalip Date: Fri, 10 Feb 2023 17:52:17 +0200 Subject: [PATCH 4/7] Updates on aborting process/password cancelation Signed-off-by: Apokalip --- src/service.rs | 2 +- ui/src-tauri/src/main.rs | 9 ++++++--- ui/src/App.js | 21 ++++++++++++--------- ui/src/pages/Authorize.js | 11 ++++++++++- ui/src/pages/ViewPhrase/ViewPhrasePage.js | 4 +++- ui/src/pages/ViewPhrase/ViewSecretPhrase.js | 1 + 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/service.rs b/src/service.rs index 03cc20b7..6f34fd97 100644 --- a/src/service.rs +++ b/src/service.rs @@ -217,7 +217,6 @@ where } } else { println!("Password is now known, returning auth error"); - self.authorizer.sleep().await; return Err(Error::AuthorizationError); } delay_password_retry().await; @@ -617,6 +616,7 @@ where network: Network, prompt: &String, ) -> Result { + info!("Getting stored mnemonic"); self.authorizer.lock().await.check(prompt).await?; let stored_mnemonic = self.state.lock().signer[network] .state() diff --git a/ui/src-tauri/src/main.rs b/ui/src-tauri/src/main.rs index 82fc2029..f3105272 100644 --- a/ui/src-tauri/src/main.rs +++ b/ui/src-tauri/src/main.rs @@ -276,7 +276,6 @@ impl Authorizer for User { fn sleep(&mut self) -> UnitFuture { APP_STATE.set_authorizing(false); println!("INFO: Server Sleeping"); - self.emit("abort_auth", &()); Box::pin(async move { self.validate_password().await }) } } @@ -360,7 +359,7 @@ async fn set_tray_reset(tray_handle: SystemTrayHandle, reset: bool, show_phrase: "view secret recovery phrase", "View Secret Recovery Phrase", )) - .add_item(CustomMenuItem::new("view zk address", "View ZkAddress")) + .add_item(CustomMenuItem::new("view zk address", "View zkAddress")) .add_item(CustomMenuItem::new("reset", "Delete Account")) .add_item(CustomMenuItem::new("exit", "Quit")) } else if reset { @@ -715,10 +714,14 @@ fn main() { "main" => { if APP_STATE.get_ready() { if APP_STATE.get_authorizing() { - //window(app, "main").hide().expect("Unable to hide window."); + // should not hide from here, let UI handle its authorization aborting and hiding window(app, "main") .emit("abort_auth", "Aborting Authorization") .expect("Failed to abort authorization"); + APP_STATE.set_authorizing(false); + } else { + // hide any non process showing window like show zkAddress + window(app, "main").hide().expect("Unable to hide window."); } } else { app.exit(0); diff --git a/ui/src/App.js b/ui/src/App.js index 6c3e37ca..d6c0a109 100644 --- a/ui/src/App.js +++ b/ui/src/App.js @@ -165,6 +165,7 @@ function App() { } // Case 2: we need authorization for signing a transaction. + console.log("Authorization for transaction"); await checkAndStopExportingPhrase(); let parsedAuthorizationSummary = parseTransactionSummary(event.payload.split(" ")); @@ -176,7 +177,7 @@ function App() { const listenForShowSecretPhraseRequests = async () => { console.log("[INFO]: Setup tray show secret phrase listener."); - listen('show_secret_phrase', (_event) => { + listen('show_secret_phrase', async (_event) => { getSecretRecoveryPhrase(); }) } @@ -208,15 +209,17 @@ function App() { exportingPhraseRef.current = true; } - console.log("[INFO]: Send request to export recovery phrase."); - let phrase = await invoke('get_recovery_phrase', { prompt: GET_RECOVERY_PHRASE }) - .catch(error => { - console.log("Failed getting mnemonic, either fail or abort(expected)"); - return - }); + try { + console.log("[INFO]: Send request to export recovery phrase."); + let phrase = await invoke('get_recovery_phrase', { prompt: GET_RECOVERY_PHRASE }) - if (phrase) { - setExportedSecretPhrase(phrase); + console.log("[INFO]: Request for recovery phrase passed"); + if (phrase) { + await setExportedSecretPhrase(phrase); + } + } catch(error) { + console.log("Failed getting mnemonic, either fail or aborted (expected)"); + return; } } diff --git a/ui/src/pages/Authorize.js b/ui/src/pages/Authorize.js index bd4753e5..dba66cf6 100644 --- a/ui/src/pages/Authorize.js +++ b/ui/src/pages/Authorize.js @@ -1,4 +1,5 @@ -import React, { useState } from 'react'; +import { once } from '@tauri-apps/api/event'; +import React, { useState, useEffect } from 'react'; import { Button, Input } from 'semantic-ui-react'; const Authorize = ({ @@ -11,6 +12,14 @@ const Authorize = ({ const [password, setPassword] = useState(''); const [passwordInvalid, setPasswordInvalid] = useState(false); + useEffect(() => { + once("abort_auth", async () => { + console.log("Authorization window aborting to cancel function"); + await onClickDecline(); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const onClickAuthorize = async () => { console.log("[INFO]: Authorizing."); const shouldRetry = await sendPassword(password); diff --git a/ui/src/pages/ViewPhrase/ViewPhrasePage.js b/ui/src/pages/ViewPhrase/ViewPhrasePage.js index 30d38756..1a47c8ae 100644 --- a/ui/src/pages/ViewPhrase/ViewPhrasePage.js +++ b/ui/src/pages/ViewPhrase/ViewPhrasePage.js @@ -16,9 +16,11 @@ const ViewPhrasePage = ({ useEffect(() => { once("abort_auth", async () => { + console.log("ViewPhrasePage aborting to cancel function"); await onClickCancel(); }); - }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); return (<> diff --git a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js index 0b05cb79..e6f1da5d 100644 --- a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js +++ b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js @@ -21,6 +21,7 @@ const ViewSecretPhrase = ({ } const onClickCancel = async () => { + console.log("Canceling Phrase Exporting Process"); await stopPasswordPrompt(); endExportPhrase(); } From 0856e3b25d3379b7bd3459a89e94d315cbab08de Mon Sep 17 00:00:00 2001 From: Apokalip Date: Fri, 10 Feb 2023 19:10:36 +0200 Subject: [PATCH 5/7] fixing info! error Signed-off-by: Apokalip --- src/service.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/service.rs b/src/service.rs index 6f34fd97..53b47349 100644 --- a/src/service.rs +++ b/src/service.rs @@ -616,7 +616,6 @@ where network: Network, prompt: &String, ) -> Result { - info!("Getting stored mnemonic"); self.authorizer.lock().await.check(prompt).await?; let stored_mnemonic = self.state.lock().signer[network] .state() From 90e2394a9fd9884d2e7d70b86e225061e6c288a2 Mon Sep 17 00:00:00 2001 From: Apokalip Date: Sat, 11 Feb 2023 20:45:29 +0200 Subject: [PATCH 6/7] refactor logs Signed-off-by: Apokalip --- ui/src/App.js | 6 +++--- ui/src/pages/Authorize.js | 2 +- ui/src/pages/ViewPhrase/ViewPhrasePage.js | 2 +- ui/src/pages/ViewPhrase/ViewSecretPhrase.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/src/App.js b/ui/src/App.js index d6c0a109..fafdc161 100644 --- a/ui/src/App.js +++ b/ui/src/App.js @@ -158,14 +158,14 @@ function App() { // Case 1: we need authorization for exporting the recovery phrase. if (event.payload === GET_RECOVERY_PHRASE) { - console.log("Viewing secret phrase window"); + console.log("[INFO]: Viewing secret phrase window"); navigate("/view-secret-phrase"); appWindow.show(); return; } // Case 2: we need authorization for signing a transaction. - console.log("Authorization for transaction"); + console.log("[INFO]: Authorization for transaction"); await checkAndStopExportingPhrase(); let parsedAuthorizationSummary = parseTransactionSummary(event.payload.split(" ")); @@ -218,7 +218,7 @@ function App() { await setExportedSecretPhrase(phrase); } } catch(error) { - console.log("Failed getting mnemonic, either fail or aborted (expected)"); + console.log("[WARNING]: Failed getting mnemonic, either fail or aborted (expected)"); return; } } diff --git a/ui/src/pages/Authorize.js b/ui/src/pages/Authorize.js index dba66cf6..626a03d1 100644 --- a/ui/src/pages/Authorize.js +++ b/ui/src/pages/Authorize.js @@ -14,7 +14,7 @@ const Authorize = ({ useEffect(() => { once("abort_auth", async () => { - console.log("Authorization window aborting to cancel function"); + console.log("[INFO]: Authorization window aborting to cancel function"); await onClickDecline(); }); // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/ui/src/pages/ViewPhrase/ViewPhrasePage.js b/ui/src/pages/ViewPhrase/ViewPhrasePage.js index 1a47c8ae..756e69c4 100644 --- a/ui/src/pages/ViewPhrase/ViewPhrasePage.js +++ b/ui/src/pages/ViewPhrase/ViewPhrasePage.js @@ -16,7 +16,7 @@ const ViewPhrasePage = ({ useEffect(() => { once("abort_auth", async () => { - console.log("ViewPhrasePage aborting to cancel function"); + console.log("[INFO]: ViewPhrasePage aborting to cancel function"); await onClickCancel(); }); // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js index e6f1da5d..2acea4f7 100644 --- a/ui/src/pages/ViewPhrase/ViewSecretPhrase.js +++ b/ui/src/pages/ViewPhrase/ViewSecretPhrase.js @@ -21,7 +21,7 @@ const ViewSecretPhrase = ({ } const onClickCancel = async () => { - console.log("Canceling Phrase Exporting Process"); + console.log("[INFO]: Canceling Phrase Exporting Process"); await stopPasswordPrompt(); endExportPhrase(); } From ac7464064cfe6f8a89c5f40e61dda7596e12fe56 Mon Sep 17 00:00:00 2001 From: Apokalip Date: Mon, 13 Feb 2023 15:52:49 +0200 Subject: [PATCH 7/7] Changelog Signed-off-by: Apokalip --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d330ade..f8589f8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed +- [\#289](https://github.com/Manta-Network/manta-signer/pull/289) Fix authorization state preventing consecutive transactions + +### Security + ## [1.0.1] 2023-01-24 ### Added - [\#261](https://github.com/Manta-Network/manta-signer/pull/261) Bundle Proving Keys with manta-signer (no download anymore)