diff options
Diffstat (limited to 'src/login.rs')
| -rw-r--r-- | src/login.rs | 83 |
1 files changed, 76 insertions, 7 deletions
diff --git a/src/login.rs b/src/login.rs index da19a75..a6ce76d 100644 --- a/src/login.rs +++ b/src/login.rs | |||
| @@ -1,16 +1,85 @@ | |||
| 1 | use anyhow::{Context, Result}; | 1 | use anyhow::{bail, Context, Result}; |
| 2 | use nostr::prelude::{FromSkStr, ToBech32}; | ||
| 3 | use zeroize::Zeroize; | ||
| 2 | 4 | ||
| 3 | use crate::{ | 5 | use crate::{ |
| 6 | cli_interactor::{Interactor, InteractorPrompt, PromptPasswordParms}, | ||
| 4 | config::{ConfigManagement, ConfigManager}, | 7 | config::{ConfigManagement, ConfigManager}, |
| 5 | key_handling::users::{UserManagement, UserManager}, | 8 | key_handling::{ |
| 9 | encryption::{EncryptDecrypt, Encryptor}, | ||
| 10 | users::{UserManagement, UserManager}, | ||
| 11 | }, | ||
| 6 | }; | 12 | }; |
| 7 | 13 | ||
| 8 | pub fn launch(nsec: &Option<String>) -> Result<()> { | 14 | /// handles the encrpytion and storage of key material |
| 15 | pub fn launch(nsec: &Option<String>, password: &Option<String>) -> Result<nostr::Keys> { | ||
| 16 | // if nsec parameter | ||
| 17 | if let Some(nsec_unwrapped) = nsec { | ||
| 18 | // get key or fail without prompts | ||
| 19 | let key = nostr::Keys::from_sk_str(nsec_unwrapped).context("invalid nsec parameter")?; | ||
| 20 | println!( | ||
| 21 | "logged in as {}", | ||
| 22 | &key.public_key() | ||
| 23 | .to_bech32() | ||
| 24 | .context("public key should always produce bech32")? | ||
| 25 | ); | ||
| 26 | |||
| 27 | // if password, add user to enable password login in future | ||
| 28 | if password.is_some() { | ||
| 29 | UserManager::default() | ||
| 30 | .add(nsec, password) | ||
| 31 | .context("could not store identity")?; | ||
| 32 | } | ||
| 33 | return Ok(key); | ||
| 34 | } | ||
| 35 | |||
| 36 | // if encrypted nsec stored, attempt password | ||
| 9 | let cfg = ConfigManager | 37 | let cfg = ConfigManager |
| 10 | .load() | 38 | .load() |
| 11 | .context("failed to load application config")?; | 39 | .context("failed to load application config")?; |
| 12 | if !cfg.users.is_empty() { | 40 | let key = if let Some(user) = cfg.users.last() { |
| 13 | println!("logged in as {}", cfg.users[0].nsec); | 41 | let mut pass = if let Some(p) = password.clone() { |
| 14 | } | 42 | p |
| 15 | UserManager::default().add(nsec) | 43 | } else { |
| 44 | println!( | ||
| 45 | "login as {}", | ||
| 46 | &user | ||
| 47 | .public_key | ||
| 48 | .to_bech32() | ||
| 49 | .context("public key should always produce bech32")? | ||
| 50 | ); | ||
| 51 | Interactor::default() | ||
| 52 | .password(PromptPasswordParms::default().with_prompt("password")) | ||
| 53 | .context("failed to get password input from interactor.password")? | ||
| 54 | }; | ||
| 55 | |||
| 56 | let key_result = Encryptor | ||
| 57 | .decrypt_key(&user.encrypted_key, pass.as_str()) | ||
| 58 | .context("failed to decrypt key with provided password"); | ||
| 59 | pass.zeroize(); | ||
| 60 | |||
| 61 | key_result.context(format!( | ||
| 62 | "failed to log in as {}", | ||
| 63 | &user | ||
| 64 | .public_key | ||
| 65 | .to_bech32() | ||
| 66 | .context("public key should always produce bech32")? | ||
| 67 | ))? | ||
| 68 | } else { | ||
| 69 | // no nsec but password supplied | ||
| 70 | if password.is_some() { | ||
| 71 | bail!("no nsec available to decrypt with specified password"); | ||
| 72 | } | ||
| 73 | // otherwise add new user with nsec and password prompts | ||
| 74 | UserManager::default() | ||
| 75 | .add(nsec, password) | ||
| 76 | .context("failed to add user")? | ||
| 77 | }; | ||
| 78 | println!( | ||
| 79 | "logged in as {}", | ||
| 80 | &key.public_key() | ||
| 81 | .to_bech32() | ||
| 82 | .context("public key should always produce bech32")? | ||
| 83 | ); | ||
| 84 | Ok(key) | ||
| 16 | } | 85 | } |