diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/login/fresh.rs | 94 |
1 files changed, 88 insertions, 6 deletions
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs index b0fbe3f..524f419 100644 --- a/src/lib/login/fresh.rs +++ b/src/lib/login/fresh.rs | |||
| @@ -5,7 +5,7 @@ use console::Style; | |||
| 5 | use dialoguer::theme::{ColorfulTheme, Theme}; | 5 | use dialoguer::theme::{ColorfulTheme, Theme}; |
| 6 | use nostr::nips::{nip05, nip46::NostrConnectURI}; | 6 | 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::{EventBuilder, Keys, Metadata, NostrSigner, PublicKey, ToBech32, Url}; |
| 9 | use qrcode::QrCode; | 9 | use qrcode::QrCode; |
| 10 | use tokio::{signal, sync::Mutex}; | 10 | use tokio::{signal, sync::Mutex}; |
| 11 | 11 | ||
| @@ -24,7 +24,7 @@ use crate::{ | |||
| 24 | Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms, | 24 | Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms, |
| 25 | PromptInputParms, PromptPasswordParms, | 25 | PromptInputParms, PromptPasswordParms, |
| 26 | }, | 26 | }, |
| 27 | client::Connect, | 27 | client::{send_events, Connect}, |
| 28 | git::{remove_git_config_item, save_git_config_item, Repo, RepoActions}, | 28 | git::{remove_git_config_item, save_git_config_item, Repo, RepoActions}, |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| @@ -63,10 +63,14 @@ pub async fn fresh_login_or_signup( | |||
| 63 | continue; | 63 | continue; |
| 64 | } | 64 | } |
| 65 | }, | 65 | }, |
| 66 | 2 => { | 66 | 2 => match signup(client).await { |
| 67 | eprintln!("TODO create account..."); | 67 | Ok(Some(res)) => break res, |
| 68 | continue; | 68 | Ok(None) => continue, |
| 69 | } | 69 | Err(e) => { |
| 70 | eprintln!("error getting fresh signer from signup: {e}"); | ||
| 71 | continue; | ||
| 72 | } | ||
| 73 | }, | ||
| 70 | _ => { | 74 | _ => { |
| 71 | display_login_help_content().await; | 75 | display_login_help_content().await; |
| 72 | continue; | 76 | continue; |
| @@ -566,6 +570,84 @@ fn silently_save_to_git_config( | |||
| 566 | Ok(()) | 570 | Ok(()) |
| 567 | } | 571 | } |
| 568 | 572 | ||
| 573 | async fn signup( | ||
| 574 | #[cfg(test)] client: Option<&MockConnect>, | ||
| 575 | #[cfg(not(test))] client: Option<&Client>, | ||
| 576 | ) -> Result< | ||
| 577 | Option<( | ||
| 578 | Arc<dyn NostrSigner>, | ||
| 579 | PublicKey, | ||
| 580 | SignerInfo, | ||
| 581 | SignerInfoSource, | ||
| 582 | )>, | ||
| 583 | > { | ||
| 584 | eprintln!("create account"); | ||
| 585 | loop { | ||
| 586 | let name = Interactor::default() | ||
| 587 | .input( | ||
| 588 | PromptInputParms::default() | ||
| 589 | .with_prompt("user display name") | ||
| 590 | .optional() | ||
| 591 | .dont_report(), | ||
| 592 | ) | ||
| 593 | .context("failed to get display name input from interactor")?; | ||
| 594 | if name.is_empty() { | ||
| 595 | show_prompt_error("emtpy display name", ""); | ||
| 596 | match Interactor::default().choice( | ||
| 597 | PromptChoiceParms::default() | ||
| 598 | .with_default(0) | ||
| 599 | .with_choices(vec![ | ||
| 600 | "enter non-empty display name".to_string(), | ||
| 601 | "back to login menu".to_string(), | ||
| 602 | ]) | ||
| 603 | .dont_report(), | ||
| 604 | )? { | ||
| 605 | 0 => continue, | ||
| 606 | _ => break Ok(None), | ||
| 607 | } | ||
| 608 | } | ||
| 609 | let keys = nostr::Keys::generate(); | ||
| 610 | let nsec = keys.secret_key().to_bech32()?; | ||
| 611 | show_prompt_success("user display name", &name); | ||
| 612 | let signer_info = SignerInfo::Nsec { | ||
| 613 | nsec, | ||
| 614 | password: None, | ||
| 615 | npub: Some(keys.public_key().to_bech32()?), | ||
| 616 | }; | ||
| 617 | let public_key = keys.public_key(); | ||
| 618 | if let Some(client) = client { | ||
| 619 | let profile = | ||
| 620 | EventBuilder::metadata(&Metadata::new().name(name)).sign_with_keys(&keys)?; | ||
| 621 | let relay_list = EventBuilder::relay_list( | ||
| 622 | client | ||
| 623 | .get_fallback_relays() | ||
| 624 | .iter() | ||
| 625 | .map(|s| (Url::parse(s).unwrap(), None)), | ||
| 626 | ) | ||
| 627 | .sign_with_keys(&keys)?; | ||
| 628 | eprintln!("publishing user profile to relays"); | ||
| 629 | send_events( | ||
| 630 | client, | ||
| 631 | None, | ||
| 632 | vec![profile, relay_list], | ||
| 633 | client.get_fallback_relays().clone(), | ||
| 634 | vec![], | ||
| 635 | true, | ||
| 636 | false, | ||
| 637 | ) | ||
| 638 | .await?; | ||
| 639 | } | ||
| 640 | eprintln!("TODO: advice about using in other clients"); | ||
| 641 | break Ok(Some(( | ||
| 642 | Arc::new(keys), | ||
| 643 | public_key, | ||
| 644 | signer_info, | ||
| 645 | // TODO factor in source | ||
| 646 | SignerInfoSource::GitGlobal, | ||
| 647 | ))); | ||
| 648 | } | ||
| 649 | } | ||
| 650 | |||
| 569 | async fn display_login_help_content() { | 651 | async fn display_login_help_content() { |
| 570 | let mut printer = Printer::default(); | 652 | let mut printer = Printer::default(); |
| 571 | let title_style = Style::new().bold().fg(console::Color::Yellow); | 653 | let title_style = Style::new().bold().fg(console::Color::Yellow); |