Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix authorization #289

Merged
merged 8 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Security

## 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)
Expand Down
3 changes: 2 additions & 1 deletion src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,11 @@ where
.is_ok()
{
self.authorizer.sleep().await;
println!("Password is ok");
return Ok(());
}
} else {
println!("Password is now known, returning auth error");
return Err(Error::AuthorizationError);
}
delay_password_retry().await;
Expand Down Expand Up @@ -445,7 +447,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();
}
Expand Down
22 changes: 13 additions & 9 deletions ui/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,15 @@ impl Authorizer for User {
T: Serialize,
{
APP_STATE.set_authorizing(true);
println!("INFO: Server Awake");
self.emit("authorize", prompt);
Box::pin(async move {})
}

#[inline]
fn sleep(&mut self) -> UnitFuture {
APP_STATE.set_authorizing(false);
self.emit("abort_auth", &());
println!("INFO: Server Sleeping");
Box::pin(async move { self.validate_password().await })
}
}
Expand Down Expand Up @@ -358,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 {
Expand Down Expand Up @@ -569,11 +570,10 @@ async fn get_recovery_phrase(
server_store: State<'_, ServerStore>,
) -> Result<Mnemonic, ()> {
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(())
}
Expand Down Expand Up @@ -713,11 +713,15 @@ 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() {
// should not hide from here, let UI handle its authorization aborting and hiding
window(app, "main")
.emit_all("abort_auth", "Aborting Authorization")
.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);
Expand Down
18 changes: 13 additions & 5 deletions ui/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,14 @@ function App() {

// Case 1: we need authorization for exporting the recovery phrase.
if (event.payload === GET_RECOVERY_PHRASE) {
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("[INFO]: Authorization for transaction");
await checkAndStopExportingPhrase();
let parsedAuthorizationSummary = parseTransactionSummary(event.payload.split(" "));

Expand All @@ -175,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();
})
}
Expand Down Expand Up @@ -207,11 +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 });
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("[WARNING]: Failed getting mnemonic, either fail or aborted (expected)");
return;
}
}

Expand Down
5 changes: 3 additions & 2 deletions ui/src/pages/Authorize.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ const Authorize = ({
const [password, setPassword] = useState('');
const [passwordInvalid, setPasswordInvalid] = useState(false);


useEffect(() => {
once("abort_auth", async () => {
console.log("[INFO]: Authorization window aborting to cancel function");
await onClickDecline();
});
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const onClickAuthorize = async () => {
console.log("[INFO]: Authorizing.");
Expand Down
8 changes: 5 additions & 3 deletions ui/src/pages/ViewPhrase/ViewPhrasePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ const ViewPhrasePage = ({
onClickSubmitPassword,
onClickCancel
}) => {

useEffect(() => {
once("abort_auth", async () => {
console.log("[INFO]: ViewPhrasePage aborting to cancel function");
await onClickCancel();
});
});

// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (<>

<div className='main-logo-container view-phrase'>
Expand Down
3 changes: 2 additions & 1 deletion ui/src/pages/ViewPhrase/ViewSecretPhrase.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import React, { useState } from 'react';
import ViewPhrasePage from "./ViewPhrasePage";
import ViewPhraseSuccess from "./ViewPhraseSuccess";

Expand All @@ -21,6 +21,7 @@ const ViewSecretPhrase = ({
}

const onClickCancel = async () => {
console.log("[INFO]: Canceling Phrase Exporting Process");
await stopPasswordPrompt();
endExportPhrase();
}
Expand Down