diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-22 09:54:19 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-22 09:56:35 +0000 |
| commit | f42da615be7c994581b49ed9d5c17325b904b8f6 (patch) | |
| tree | a9592428fb17b4337d315384a4658a329b404efe /src | |
| parent | f79014235e85554e3661b3f2a02b8fa88bc192ff (diff) | |
feat(login): auto-proceed upon signer response
don't ask the user to press any key to proceed once the signer
successfully responds.
various approaches were to tried await either any key press or the
signer reponse such as `tokio::oneshot`, `tokio::mpsc` and
`tokio::watch` but all would keep the process running until key
press. this solution of aborting with `signal::ctrl_c` prevents the
work around of asking the user to press any key upon
the signer reponse.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/login/fresh.rs | 65 |
1 files changed, 30 insertions, 35 deletions
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs index 3e88f68..bd5837a 100644 --- a/src/lib/login/fresh.rs +++ b/src/lib/login/fresh.rs | |||
| @@ -7,7 +7,7 @@ use nostr::nips::{nip05, nip46::NostrConnectURI}; | |||
| 7 | use nostr_connect::client::NostrConnect; | 7 | use nostr_connect::client::NostrConnect; |
| 8 | use nostr_sdk::{Keys, NostrSigner, PublicKey, ToBech32, Url}; | 8 | use nostr_sdk::{Keys, NostrSigner, PublicKey, ToBech32, Url}; |
| 9 | use qrcode::QrCode; | 9 | use qrcode::QrCode; |
| 10 | use tokio::sync::{oneshot, Mutex}; | 10 | use tokio::{signal, sync::Mutex}; |
| 11 | 11 | ||
| 12 | use super::{ | 12 | use super::{ |
| 13 | key_encryption::decrypt_key, | 13 | key_encryption::decrypt_key, |
| @@ -297,8 +297,10 @@ pub async fn get_fresh_nip46_signer( | |||
| 297 | .println("login to nostr with remote signer via nostr connect".to_string()); | 297 | .println("login to nostr with remote signer via nostr connect".to_string()); |
| 298 | printer_locked.println("scan QR code in signer app (eg Amber):".to_string()); | 298 | printer_locked.println("scan QR code in signer app (eg Amber):".to_string()); |
| 299 | printer_locked.printlns(generate_qr(&url.to_string())?); | 299 | printer_locked.printlns(generate_qr(&url.to_string())?); |
| 300 | printer_locked | 300 | printer_locked.println( |
| 301 | .println("scan QR code in signer app or press any key to abort...".to_string()); | 301 | "scan QR code in signer app or use ctrl + c to go back to login menu..." |
| 302 | .to_string(), | ||
| 303 | ); | ||
| 302 | } | 304 | } |
| 303 | 1 => { | 305 | 1 => { |
| 304 | printer_locked | 306 | printer_locked |
| @@ -309,12 +311,15 @@ pub async fn get_fresh_nip46_signer( | |||
| 309 | url.to_string(), | 311 | url.to_string(), |
| 310 | ); | 312 | ); |
| 311 | printer_locked.println("".to_string()); | 313 | printer_locked.println("".to_string()); |
| 312 | printer_locked | 314 | printer_locked.println( |
| 313 | .println("paste url into signer app or press any key to abort...".to_string()); | 315 | "paste this url into signer app or use ctrl + c to go back to login menu..." |
| 316 | .to_string(), | ||
| 317 | ); | ||
| 314 | } | 318 | } |
| 315 | _ => { | 319 | _ => { |
| 316 | printer_locked.println( | 320 | printer_locked.println( |
| 317 | "add / approve in your signer or press any key to abort... ".to_string(), | 321 | "add / approve in your signer or use ctrl + c to go back to login menu..." |
| 322 | .to_string(), | ||
| 318 | ); | 323 | ); |
| 319 | } | 324 | } |
| 320 | } | 325 | } |
| @@ -382,43 +387,33 @@ pub async fn listen_for_remote_signer( | |||
| 382 | nostr_connect_url: &NostrConnectURI, | 387 | nostr_connect_url: &NostrConnectURI, |
| 383 | printer: Arc<Mutex<Printer>>, | 388 | printer: Arc<Mutex<Printer>>, |
| 384 | ) -> Result<(Arc<dyn NostrSigner>, PublicKey, NostrConnectURI)> { | 389 | ) -> Result<(Arc<dyn NostrSigner>, PublicKey, NostrConnectURI)> { |
| 385 | let (tx, rx) = oneshot::channel(); | ||
| 386 | let printer_clone = Arc::clone(&printer); | ||
| 387 | let app_key = app_key.clone(); | 390 | let app_key = app_key.clone(); |
| 388 | let nostr_connect_url_clone = nostr_connect_url.clone(); | 391 | let nostr_connect_url_clone = nostr_connect_url.clone(); |
| 389 | let qr_listener = tokio::spawn(async move { | ||
| 390 | if let Ok(nostr_connect) = NostrConnect::new( | ||
| 391 | nostr_connect_url_clone, | ||
| 392 | app_key, | ||
| 393 | Duration::from_secs(10 * 60), | ||
| 394 | None, | ||
| 395 | ) { | ||
| 396 | let signer: Arc<dyn NostrSigner> = Arc::new(nostr_connect); | ||
| 397 | if let Ok(pub_key) = signer.get_public_key().await { | ||
| 398 | let mut printer_locked = printer_clone.lock().await; | ||
| 399 | printer_locked.clear_all(); | ||
| 400 | 392 | ||
| 401 | printer_locked.println_with_custom_formatting( | 393 | let nostr_connect = NostrConnect::new( |
| 402 | format!( | 394 | nostr_connect_url_clone, |
| 403 | "{}", | 395 | app_key, |
| 404 | Style::new().bold().apply_to("connected to remote signer"), | 396 | Duration::from_secs(10 * 60), |
| 405 | ), | 397 | None, |
| 406 | "connected to remote signer".to_string(), | 398 | )?; |
| 407 | ); | 399 | let signer: Arc<dyn NostrSigner> = Arc::new(nostr_connect); |
| 408 | printer_locked.println("press any key to continue...".to_string()); | 400 | let pubkey_future = signer.get_public_key(); |
| 409 | let _ = tx.send(Some((signer, pub_key))); | 401 | |
| 410 | } else { | 402 | // wait for signer response or ctrl + c |
| 411 | let _ = tx.send(None); | 403 | let res = tokio::select! { |
| 412 | } | 404 | pubkey_result = pubkey_future => { |
| 405 | Some(pubkey_result) | ||
| 406 | }, | ||
| 407 | _ = signal::ctrl_c() => { | ||
| 408 | None | ||
| 413 | } | 409 | } |
| 414 | }); | 410 | }; |
| 415 | let _ = console::Term::stderr().read_char(); | 411 | |
| 416 | qr_listener.abort(); | ||
| 417 | let printer_clone = Arc::clone(&printer); | 412 | let printer_clone = Arc::clone(&printer); |
| 418 | let mut printer = printer_clone.lock().await; | 413 | let mut printer = printer_clone.lock().await; |
| 419 | printer.clear_all(); | 414 | printer.clear_all(); |
| 420 | 415 | ||
| 421 | if let Some((signer, public_key)) = rx.await? { | 416 | if let Some(Ok(public_key)) = res { |
| 422 | let bunker_url = NostrConnectURI::Bunker { | 417 | let bunker_url = NostrConnectURI::Bunker { |
| 423 | // TODO the remote signer pubkey may not be the user pubkey | 418 | // TODO the remote signer pubkey may not be the user pubkey |
| 424 | remote_signer_public_key: public_key, | 419 | remote_signer_public_key: public_key, |